Скопируйте PDF-аннотации через C # - PullRequest
2 голосов
/ 30 июля 2010

У меня есть поток (файл PDF с аннотациями) и другой поток (тот же файл PDF без аннотаций).Я использую потоки, потому что мне нужно выполнить эти операции в памяти.Мне нужно скопировать аннотации из первого документа в другой.Аннотации могут быть разными: комментарии, выделения и др.Поэтому лучше копировать аннотации без их анализа.

Можете ли вы посоветовать мне какую-нибудь полезную библиотеку PDF для .NET?И образец для этой проблемы.

Ответы [ 2 ]

0 голосов
/ 13 апреля 2017

Вы можете использовать этот пример для iTextSharp для решения вашей проблемы (в этом примере копируется список файлов PDF с аннотациями в новый файл PDF):

var output = new MemoryStream();

using (var document = new Document(PageSize.A4, 70f, 70f, 20f, 20f))
{
    var readers = new List<PdfReader>();
    var writer = PdfWriter.GetInstance(document, output);

    writer.CloseStream = false;

    document.Open();

    const Int32 requiredWidth = 500;
    const Int32 zeroBottom = 647;
    const Int32 left = 50;

    Action<String, Action> inlcudePdfInDocument = (filename, e) =>
    {
         var reader = new PdfReader(filename);
         readers.Add(reader);

         var pageCount = reader.NumberOfPages;
         for (var i = 0; i < pageCount; i++)
         { 
             e?.Invoke();
             var imp = writer.GetImportedPage(reader, (i + 1));

             var scale = requiredWidth / imp.Width;
             var height = imp.Height * scale;

             writer.DirectContent.AddTemplate(imp, scale, 0, 0, scale, left, zeroBottom - height);

             var annots = reader.GetPageN(i + 1).GetAsArray(PdfName.ANNOTS);
             if (annots != null && annots.Size != 0)
             {
                 foreach (var a in annots)
                 {
                     var newannot = new PdfAnnotation(writer, new Rectangle(0, 0));
                     var annotObj = (PdfDictionary) PdfReader.GetPdfObject(a);
                     newannot.PutAll(annotObj);
                     var rect = newannot.GetAsArray(PdfName.RECT);
                     rect[0] = new PdfNumber(((PdfNumber)rect[0]).DoubleValue * scale + left); // Left
                     rect[1] = new PdfNumber(((PdfNumber)rect[1]).DoubleValue * scale); // top
                     rect[2] = new PdfNumber(((PdfNumber)rect[2]).DoubleValue * scale + left); // right
                     rect[3] = new PdfNumber(((PdfNumber)rect[3]).DoubleValue * scale); // bottom
                     writer.AddAnnotation(newannot);
                 }
             }

             document.NewPage();
         }

     }

    foreach (var apprPdf in pdfs)
    {
        document.NewPage();

        inlcudePdfInDocument(apprPdf.Pdf, null);
    }

    document.Close();
    readers.ForEach(x => x.Close());
}

output.Position = 0;
return output;

PdfReader имеет конструктор, который принимает массив байтов, чтобы вы могли адаптировать его для MemoryStream.

0 голосов
/ 30 июля 2010

Я использую ITextSharp, который разветвляется из IText (реализация Java для редактирования PDF).

http://sourceforge.net/projects/itextsharp/

http://itextpdf.com/

Редактировать - эточто вам нужно сделать (не проверено, но должно быть близко):

using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

// return processed stream (a new MemoryStream) 
public Stream copyAnnotations(Stream sourcePdfStream, Stream destinationPdfStream)
{
    // Create new document (IText)
    Document outdoc = new Document(PageSize.A4);

    // Seek to Stream start and create Reader for input PDF
    m.Seek(0, SeekOrigin.Begin);
    PdfReader inputPdfReader = new PdfReader(sourcePdfStream);

    // Seek to Stream start and create Reader for destination PDF
    m.Seek(0, SeekOrigin.Begin);
    PdfReader destinationPdfReader = new PdfReader(destinationPdfStream);

    // Create a PdfWriter from for new a pdf destination stream
    // You should write into a new stream here!
    Stream processedPdf = new MemoryStream();
    PdfWriter pdfw = PdfWriter.GetInstance(outdoc, processedPdf);

    // do not close stream if we've read everything
    pdfw.CloseStream = false;

    // Open document
    outdoc.Open();

    // get number of pages
    int numPagesIn = inputPdfReader.NumberOfPages;
    int numPagesOut = destinationPdfReader.NumberOfPages;

    int max = numPagesIn;

    // Process max number of pages
    if (max<numPagesOut)
    {
        throw new Exception("Impossible - different number of pages");
    }
    int i = 0;

    // Process Pdf pages
    while (i < max)
    {
        // Import pages from corresponding reader
        PdfImportedPage pageIn = writer.inputPdfReader(reader, i);
        PdfImportedPage pageOut = writer.destinationPdfReader(reader, i);

        // Get named destinations (annotations
        List<Annotations> toBeAdded = ParseInAndOutAndGetAnnotations(pageIn, pageOut);

        // add your annotations
        foreach (Annotation anno in toBeAdded) pageOut.Add(anno);

        // Add processed page to output PDFWriter
        outdoc.Add(pageOut);
    }

    // PDF creation finished
    outdoc.Close();

    // your new destination stream is processedPdf
    return processedPdf;
}

Реализация ParseInAndOutAndGetAnnotations (pageIn, pageOut) должна отражать ваши аннотации.

Вот хороший пример с аннотациями: http://www.java2s.com/Open-Source/Java-Document/PDF/pdf-itext/com/lowagie/text/pdf/internal/PdfAnnotationsImp.java.htm

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...