คัดลอกคำอธิบายประกอบ PDF ผ่าน C#

ฉันมีสตรีม (ไฟล์ PDF พร้อมคำอธิบายประกอบ) และสตรีมอื่น (ไฟล์ PDF เดียวกันที่ไม่มีคำอธิบายประกอบ) ฉันใช้สตรีมเพราะฉันต้องดำเนินการนี้ในหน่วยความจำ ฉันต้องคัดลอกคำอธิบายประกอบจากเอกสารฉบับแรกไปยังเอกสารอื่น คำอธิบายประกอบอาจแตกต่างกัน: ความคิดเห็น การไฮไลต์ และอื่นๆ ดังนั้นจึงเป็นการดีกว่าที่จะคัดลอกคำอธิบายประกอบโดยไม่ต้องแยกวิเคราะห์

คุณช่วยแนะนำไลบรารี PDF ที่เป็นประโยชน์สำหรับ .NET ให้ฉันได้ไหม และตัวอย่างบางส่วนสำหรับปัญหานี้


person Mykhail Galushko    schedule 30.07.2010    source แหล่งที่มา


คำตอบ (2)


ฉันใช้ ITextSharp ซึ่งแยกจาก IText (การแก้ไข pdf การใช้ java fpr)

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< /ก>

person Andreas Rehm    schedule 30.07.2010
comment
ฉันพยายามใช้ ITextSharp แต่ไม่พบตัวอย่างที่ดีในการคัดลอกคำอธิบายประกอบ - person Mykhail Galushko; 30.07.2010
comment
ฉันได้เพิ่มตัวอย่างเล็กๆ น้อยๆ แล้ว คุณต้องปรับเปลี่ยน มันเป็นเพียงการเพิ่มคำอธิบายประกอบ แยกวิเคราะห์แต่ละหน้าได้ง่ายด้วย iTextSharp - นั่นคือสิ่งที่คุณต้องทำ - person Andreas Rehm; 30.07.2010
comment
ขอบคุณมากสำหรับความช่วยเหลือของคุณ. iTextSharp เป็นห้องสมุดที่ยอดเยี่ยม แต่บางครั้งก็มีตัวอย่างไม่เพียงพอ - person Mykhail Galushko; 01.08.2010
comment
คุณช่วยตรวจสอบรหัสของคุณได้ไหม? คุณขาดการชะลอตัวของตัวแปรไปบ้าง - person Christian Payne; 28.02.2011
comment
การใช้งานจริงของ ParseInAndOutAndGetAnnotations หายไปและลิงก์ที่ชี้ไปนั้นใช้งานไม่ได้ ดังนั้นตอนนี้ให้เดาวิธีการใช้แล้ว - person Peter Staev; 23.06.2016

คุณสามารถใช้ตัวอย่างนี้สำหรับ 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 ได้

person Andrei    schedule 13.04.2017
comment
ดูเหมือนว่าจะใช้ได้เฉพาะกับคำอธิบายประกอบแบบธรรมดาซึ่งไม่ได้อ้างอิงวัตถุทางอ้อมเพิ่มเติม - person mkl; 14.04.2017