通过C#复制pdf注释

时间:2010-07-30 14:50:56

标签: c# .net pdf

我有一个流(带注释的PDF文件)和另一个流(没有注释的相同PDF文件)。我使用流,因为我需要在内存中执行此操作。 我需要将注释从第一个文档复制到另一个文档。注释可以是不同的:注释,突出显示和其他。因此,最好在不解析注释的情况下复制注释。

你能为我建议一些有用的.NET PDF库吗?还有一些样本可以解决这个问题。

2 个答案:

答案 0 :(得分:0)

我正在使用从IText分叉的ITextSharp(java实现fpr 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

答案 1 :(得分:0)

您可以将此示例用于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调整它。