8

これを行う方法の例を探して Web を精査しました。必要以上に関与しているように見えるものをいくつか見つけました。私の質問は、iTextSharp を使用して、ある PDF ドキュメントを別の PDF ドキュメントに追加するかなり簡潔な方法はありますか?

これに 3 番目のファイルが含まれないことが最適です。最初の PDF ドキュメントを開き、2 番目の PDF ドキュメントを最初の PDF ドキュメントに追加して、両方を閉じます。

4

4 に答える 4

14

私は本当に何かが欠けているかもしれませんが、もっと簡単なことをしました。このソリューションはおそらくブックマークを更新しないことを認めますが(これまでの最良の回答のように)、私にとっては問題なく機能します。ドキュメントを入力可能なフォームにマージしていたので、PdfCopy の代わりに PdfCopyFields を使用しました。

コードは次のとおりです (実際のコードをより見やすくするためにすべてのエラー処理を削除しました。コードを使用する予定がある場合は、try..finally を追加して、開いているリソースを閉じます)。

    void MergePdfStreams(List<Stream> Source, Stream Dest)
    {
        PdfCopyFields copy = new PdfCopyFields(Dest);

        foreach (Stream source in Source)
        {
            PdfReader reader = new PdfReader(source);
            copy.AddDocument(reader);
        }

        copy.Close();
    }

FileStream、MemoryStream など、任意のストリームを渡すことができます (データベースから PDF を読み取る場合に便利で、一時ファイルは必要ありません)。

使用例:

    void TestMergePdfStreams()
    {
        List<Stream> sources = new List<Stream>()
        {
            new FileStream("template1.pdf", FileMode.Open),
            new FileStream("template2.pdf", FileMode.Open),
            new MemoryStream((byte[])someDataRow["PDF_COLUMN_NAME"])
        };

        MergePdfStreams(sources, new FileStream("MergedOutput.pdf", FileMode.Create));
    }
于 2010-03-03T20:03:42.353 に答える
5

わかりました、簡単ではありませんが、機能し、驚くほど高速です。(そして、3 番目のファイルを使用します。open や append などはありません。) docs/examples でこれを「発見」しました。コードは次のとおりです。

private void CombineMultiplePDFs( string[] fileNames, string outFile ) {
    int pageOffset = 0;
    ArrayList master = new ArrayList();
    int f = 0;

    Document document = null;
    PdfCopy writer = null;
    while ( f < fileNames.Length ) {
        // we create a reader for a certain document
        PdfReader reader = new PdfReader( fileNames[ f ] );
        reader.ConsolidateNamedDestinations();
        // we retrieve the total number of pages
        int n = reader.NumberOfPages;
        ArrayList bookmarks = SimpleBookmark.GetBookmark( reader );
        if ( bookmarks != null ) {
            if ( pageOffset != 0 ) {
                SimpleBookmark.ShiftPageNumbers( bookmarks, pageOffset, null );
            }
            master.AddRange( bookmarks );
        }
        pageOffset += n;

        if ( f == 0 ) {
            // step 1: creation of a document-object
            document = new Document( reader.GetPageSizeWithRotation( 1 ) );
            // step 2: we create a writer that listens to the document
            writer = new PdfCopy( document, new FileStream( outFile, FileMode.Create ) );
            // step 3: we open the document
            document.Open();
        }
        // step 4: we add content
        for ( int i = 0; i < n; ) {
            ++i;
            if ( writer != null ) {
                PdfImportedPage page = writer.GetImportedPage( reader, i );
                writer.AddPage( page );
            }
        }
        PRAcroForm form = reader.AcroForm;
        if ( form != null && writer != null ) {
            writer.CopyAcroForm( reader );
        }
        f++;
    }
    if ( master.Count > 0 && writer != null ) {
        writer.Outlines = master;
    }
    // step 5: we close the document
    if ( document != null ) {
        document.Close();
    }
}
于 2009-02-20T14:28:36.350 に答える
2

はい。PdfManipulation というクラスが iText フォーラムに投稿されているのを見たことがあります。ただし、そのクラスを使用すると、3 番目のファイルが必要になります。

クラスはもともと VB.Net にあります。vbforums.comの投稿からダウンロードしました。ただし、ファイルのマージ機能はないようなので、そのクラスのコードに基づいて作成しました。

これは、iTextSharp のないマシンで作成されました。これにはバグがあるかもしれません。ページ番号が 0 から始まるか 1 から始まるかさえわかりません。しかし、それを試してみてください。

public static void MergePdfFiles(IEnumerable<string> files, string output) {
    iTextSharp.text.Document doc;
    iTextSharp.text.pdf.PdfCopy pdfCpy;

    doc = new iTextSharp.text.Document();
    pdfCpy = new iTextSharp.text.pdf.PdfCopy(doc, new System.IO.FileStream(output, System.IO.FileMode.Create));
    doc.Open();

    foreach (string file in files) {
        // initialize a reader
        iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(file);
        int pageCount = reader.NumberOfPages;

        // set page size for the documents
        doc.SetPageSize(reader.GetPageSizeWithRotation(1));

        for (int pageNum = 1; pageNum <= pageCount; pageNum++) {
            iTextSharp.text.pdf.PdfImportedPage page = pdfCpy.GetImportedPage(reader, pageNum);
            pdfCpy.AddPage(page);
        }

        reader.Close();
    }

    doc.Close();
}
于 2009-02-19T22:34:48.980 に答える
0

PDFファイルの場合はどうすればよいかわかりませんが、Postscriptの場合はファイルを連結するだけです。pdf2ps と ps2pdf がインストールされている場合は、以下のようにします。

pdf2ps file1.pdf file1.ps
pdf2ps file2.pdf file2.ps
cat file1.ps file2.ps > combined.ps
ps2pdf combined.ps combined.pdf

私は pdf2ps または ps2pdf の専門家ではありません。私はこれまでps2pdfしか使用していませんでしたが、使用するとテキストがテキストのままになります(結果のpdfからテキストを選択してコピーすることはできます)。上記の手順(pdf-> ps、結合、ps-> pdf)を実行すると、画像のような結果のpdfになります。理由はわかりません。

于 2009-02-19T23:07:13.550 に答える