19

複数の PDF ファイル (実行時に生成) をマージしてItextSharpから印刷する方法。

次のリンクを見つけましたが、その方法では、pdf ファイルが保存されていることを考慮して pdf 名が必要であり、これは私の場合ではありません。


pdf filesこの方法で変換するレポートが複数あります。

private void AddReportToResponse(LocalReport followsReport)
{
    string mimeType;
    string encoding;
    string extension;
    string[] streams = new string[100];
    Warning[] warnings = new Warning[100];
    byte[] pdfStream = followsReport.Render("PDF", "", out mimeType, out encoding, out extension, out streams, out warnings);
  //Response.Clear();
  //Response.ContentType = mimeType;
  //Response.AddHeader("content-disposition", "attachment; filename=Application." + extension);
  //Response.BinaryWrite(pdfStream);
  //Response.End();
}

Bytes生成されたすべてのファイル ( ) を 1 つの pdf ファイルにマージして印刷したい

4

6 に答える 6

53

iText(Sharp) を使用してソース ドキュメントをマージする場合、2 つの基本的な状況があります。

  1. ドキュメントをマージして、ページを元の形式で取得し、できるだけ多くのコンテンツとインタラクティブな注釈を転送する必要があります。Pdf*Copy*この場合、クラスのファミリーのメンバーに基づくソリューションを使用する必要があります。

  2. 実際には、ソース ドキュメントのページを新しいドキュメントに統合したいが、新しいドキュメントで一般的な形式を管理し、元のドキュメントのインタラクティブな機能 (注釈など) を気にしない (または取り除きたい)そのうちの)。PdfWriterこの場合、クラスに基づくソリューションを使用する必要があります。

詳細については、 iText in Action — 2nd Editionの第 6 章(特にセクション 6.4) を参照してください。Java サンプル コードはここから、C# 化されたバージョンはここからアクセスできます。

使用する簡単なサンプルPdfCopyConcatenate.java / Concatenate.csです。コードの中心部分は次のとおりです。

byte[] mergedPdf = null;
using (MemoryStream ms = new MemoryStream())
{
    using (Document document = new Document())
    {
        using (PdfCopy copy = new PdfCopy(document, ms))
        {
            document.Open();

            for (int i = 0; i < pdf.Count; ++i)
            {
                PdfReader reader = new PdfReader(pdf[i]);
                // loop over the pages in that document
                int n = reader.NumberOfPages;
                for (int page = 0; page < n; )
                {
                    copy.AddPage(copy.GetImportedPage(reader, ++page));
                }
            }
        }
    }
    mergedPdf = ms.ToArray();
}

hereは、ソース ドキュメントを直接含むpdfとして定義することもList<byte[]>(メモリ内の中間ドキュメントをマージするユース ケースに適しています) List<String>、ソース ドキュメント ファイルの名前を含む として定義することもできます (ディスクからドキュメントをマージする場合に適しています)。

参照されている章の最後にある概要は、言及されているクラスの使用法をまとめたものです。

  • PdfCopy: 1 つまたは複数の既存の PDF ドキュメントからページをコピーします。主な欠点:PdfCopy冗長なコンテンツを検出せず、フォームを連結するときに失敗します。

  • PdfCopyFields: 異なるフォームのフィールドを 1 つのフォームにまとめます。を使用してフォームを連結するときにフォーム フィールドで発生する問題を回避するために使用できますPdfCopy。メモリ使用量が問題になる場合があります。

  • PdfSmartCopy: 1 つまたは複数の既存の PDF ドキュメントからページをコピーします。PdfSmartCopyは冗長なコンテンツを検出できますが、より多くのメモリと CPU を必要としますPdfCopy

  • PdfWriter: PDF ドキュメントを最初から生成します。他の PDF ドキュメントからページをインポートできます。主な欠点は、インポートされたページのすべてのインタラクティブ機能 (注釈、ブックマーク、フィールドなど) が処理中に失われることです。

于 2013-04-11T09:39:24.110 に答える
9

iTextsharp と c# を使用して、pdf ファイルを結合しました。これは私が使用したコードです。

string[] lstFiles=new string[3];
    lstFiles[0]=@"C:/pdf/1.pdf";
    lstFiles[1]=@"C:/pdf/2.pdf";
    lstFiles[2]=@"C:/pdf/3.pdf";

    PdfReader reader = null;
    Document sourceDocument = null;
    PdfCopy pdfCopyProvider = null;
    PdfImportedPage importedPage;
    string outputPdfPath=@"C:/pdf/new.pdf";


    sourceDocument = new Document();
    pdfCopyProvider = new PdfCopy(sourceDocument, new System.IO.FileStream(outputPdfPath, System.IO.FileMode.Create));

    //Open the output file
    sourceDocument.Open();

    try
    {
        //Loop through the files list
        for (int f = 0; f < lstFiles.Length-1; f++)
        {
            int pages =get_pageCcount(lstFiles[f]);

            reader = new PdfReader(lstFiles[f]);
            //Add pages of current file
            for (int i = 1; i <= pages; i++)
            {
                importedPage = pdfCopyProvider.GetImportedPage(reader, i);
                pdfCopyProvider.AddPage(importedPage);
            }

            reader.Close();
         }
        //At the end save the output file
        sourceDocument.Close();
    }
    catch (Exception ex)
    {
        throw ex;
    }


private int get_pageCcount(string file)
{
    using (StreamReader sr = new StreamReader(File.OpenRead(file)))
    {
        Regex regex = new Regex(@"/Type\s*/Page[^s]");
        MatchCollection matches = regex.Matches(sr.ReadToEnd());

        return matches.Count;
    }
}
于 2014-03-02T02:45:07.643 に答える
5

iTextSharp-LGPL 4.1.6でテスト済み:

    public static byte[] ConcatenatePdfs(IEnumerable<byte[]> documents)
    {
        using (var ms = new MemoryStream())
        {
            var outputDocument = new Document();
            var writer = new PdfCopy(outputDocument, ms);
            outputDocument.Open();

            foreach (var doc in documents)
            {
                var reader = new PdfReader(doc);
                for (var i = 1; i <= reader.NumberOfPages; i++)
                {
                    writer.AddPage(writer.GetImportedPage(reader, i));
                }
                writer.FreeReader(reader);
                reader.Close();
            }

            writer.Close();
            outputDocument.Close();
            var allPagesContent = ms.GetBuffer();
            ms.Flush();

            return allPagesContent;
        }
    }
于 2016-10-06T13:25:31.000 に答える
5

これは、私が持っていた古いプロジェクトから取り出したコードです。それはWebアプリケーションでしたが、iTextSharpを使用してpdfファイルをマージしてから印刷していました。

public static class PdfMerger
    {
        /// <summary>
        /// Merge pdf files.
        /// </summary>
        /// <param name="sourceFiles">PDF files being merged.</param>
        /// <returns></returns>
        public static byte[] MergeFiles(List<Stream> sourceFiles)
        {
            Document document = new Document();
            MemoryStream output = new MemoryStream();

            try
            {
                // Initialize pdf writer
                PdfWriter writer = PdfWriter.GetInstance(document, output);
                writer.PageEvent = new PdfPageEvents();

                // Open document to write
                document.Open();
                PdfContentByte content = writer.DirectContent;

                // Iterate through all pdf documents
                for (int fileCounter = 0; fileCounter < sourceFiles.Count; fileCounter++)
                {
                    // Create pdf reader
                    PdfReader reader = new PdfReader(sourceFiles[fileCounter]);
                    int numberOfPages = reader.NumberOfPages;

                    // Iterate through all pages
                    for (int currentPageIndex = 1; currentPageIndex <=
                                        numberOfPages; currentPageIndex++)
                    {
                        // Determine page size for the current page
                        document.SetPageSize(
                            reader.GetPageSizeWithRotation(currentPageIndex));

                        // Create page
                        document.NewPage();
                        PdfImportedPage importedPage =
                            writer.GetImportedPage(reader, currentPageIndex);


                        // Determine page orientation
                        int pageOrientation = reader.GetPageRotation(currentPageIndex);
                        if ((pageOrientation == 90) || (pageOrientation == 270))
                        {
                            content.AddTemplate(importedPage, 0, -1f, 1f, 0, 0,
                                reader.GetPageSizeWithRotation(currentPageIndex).Height);
                        }
                        else
                        {
                            content.AddTemplate(importedPage, 1f, 0, 0, 1f, 0, 0);
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                throw new Exception("There has an unexpected exception" +
                        " occured during the pdf merging process.", exception);
            }
            finally
            {
                document.Close();
            }
            return output.GetBuffer();
        }
    }



    /// <summary>
    /// Implements custom page events.
    /// </summary>
    internal class PdfPageEvents : IPdfPageEvent
    {
        #region members
        private BaseFont _baseFont = null;
        private PdfContentByte _content;
        #endregion

        #region IPdfPageEvent Members
        public void OnOpenDocument(PdfWriter writer, Document document)
        {
            _baseFont = BaseFont.CreateFont(BaseFont.HELVETICA,
                                BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
            _content = writer.DirectContent;
        }

        public void OnStartPage(PdfWriter writer, Document document)
        { }

        public void OnEndPage(PdfWriter writer, Document document)
        { }

        public void OnCloseDocument(PdfWriter writer, Document document)
        { }

        public void OnParagraph(PdfWriter writer,
                    Document document, float paragraphPosition)
        { }

        public void OnParagraphEnd(PdfWriter writer,
                    Document document, float paragraphPosition)
        { }

        public void OnChapter(PdfWriter writer, Document document,
                                float paragraphPosition, Paragraph title)
        { }

        public void OnChapterEnd(PdfWriter writer,
                    Document document, float paragraphPosition)
        { }

        public void OnSection(PdfWriter writer, Document document,
                    float paragraphPosition, int depth, Paragraph title)
        { }

        public void OnSectionEnd(PdfWriter writer,
                    Document document, float paragraphPosition)
        { }

        public void OnGenericTag(PdfWriter writer, Document document,
                                    Rectangle rect, string text)
        { }
        #endregion

        private float GetCenterTextPosition(string text, PdfWriter writer)
        {
            return writer.PageSize.Width / 2 - _baseFont.GetWidthPoint(text, 8) / 2;
        }
    }

これは私が書いたものではありませんが、いくつかの変更を加えました。どこで見つけたのか思い出せない。PDF をマージした後、このメソッドを呼び出して JavaScript を挿入し、PDF を開いたときに印刷ダイアログを開きます。bSilent を true に変更すると、デフォルト プリンタにサイレント モードで印刷されます。

public Stream addPrintJStoPDF(Stream thePDF)
{
    MemoryStream outPutStream = null;
    PRStream finalStream = null;
    PdfDictionary page = null;
    string content = null;

    //Open the stream with iTextSharp
    var reader = new PdfReader(thePDF);

    outPutStream = new MemoryStream(finalStream.GetBytes());
    var stamper = new PdfStamper(reader, (MemoryStream)outPutStream);
    var jsText = "var res = app.setTimeOut('this.print({bUI: true, bSilent: false, bShrinkToFit: false});', 200);";
    //Add the javascript to the PDF
    stamper.JavaScript = jsText;

    stamper.FormFlattening = true;
    stamper.Writer.CloseStream = false;
    stamper.Close();

    //Set the stream to the beginning
    outPutStream.Position = 0;

    return outPutStream;
}

上記のコードがどこかから引っ張ってきたので、どれだけうまく書かれているかはわかりません.iTextSharpで深く作業していませんが、実行時に生成していたPDFをマージするのにうまくいったことは知っています.

于 2013-04-10T19:08:18.673 に答える