2010-07-30 128 views
1

我有一個流(帶有註釋的PDF文件)和另一個流(沒有註釋的同一PDF文件)。我使用流,因爲我需要在內存中執行此操作。 我需要將註釋從第一個文檔複製到另一個文檔。註釋可以不同:註釋,突出顯示和其他。因此,最好不要解析它而複製註釋。通過C#複製pdf註釋

你能否給我建議一些有用的PDF庫for .NET?還有一些針對這個問題的示例。

回答

0

我使用從IText(java實現fpr pdf編輯)分叉的ITextSharp。

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(頁面調,換頁)的實施需要反映您的註釋。

這裏是註釋一個很好的例子:http://www.java2s.com/Open-Source/Java-Document/PDF/pdf-itext/com/lowagie/text/pdf/internal/PdfAnnotationsImp.java.htm

+0

我試圖使用ITextSharp,但我沒有找到任何好的示例來複制註釋。 – 2010-07-30 15:04:08

+0

我已經添加了一個小樣本 - 您需要調整它 - 它只是添加一個註釋。使用iTextSharp輕鬆解析每個頁面 - 這就是你需要做的。 – 2010-07-30 16:30:19

+0

我改變了我的例子 - 您只需要根據註釋的類型實現您的註釋比較器 - 例如http://www.java2s.com/Open-Source/Java-Document/PDF/pdf-itext/com/lowagie/text/pdf/internal/PdfAnnotationsImp.java.htm – 2010-07-31 09:08:31

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。

+0

這似乎只適用於不引用其他間接對象的簡單註釋。 – mkl 2017-04-14 08:24:30