Jak scalić wiele plików pdf (wygenerowanych w czasie wykonywania)?

Jak połączyć wiele plików pdf (wygenerowanych w czasie pracy) przez ItextSharp, a następnie je wydrukować.

Znalazłem następujący link ale ta metoda wymaga nazw pdf biorąc pod uwagę, że pliki pdf są przechowywane i to nie jest mój przypadek .


Mam wiele raportów, które przekonwertuję na pdf files za pomocą tej metody:

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();
}

Teraz chcę połączyć wszystkie wygenerowane pliki (Bytes) w jeden plik pdf, aby go wydrukować

Author: Community, 2013-04-10

6 answers

Jeśli chcesz scalić dokumenty źródłowe za pomocą iText (Sharp), są dwie podstawowe sytuacje:

  1. Naprawdę chcesz scalić dokumenty, pozyskać strony w oryginalnym formacie, przenieść jak najwięcej ich treści i interaktywnych adnotacji, jak to możliwe. W tym przypadku należy użyć rozwiązania opartego na członku klasy Pdf*Copy*.

  2. W rzeczywistości chcesz zintegrować strony z dokumentów źródłowych w nowym dokumencie, ale chcesz nowy dokument regulujący ogólny format i nie dbający o funkcje interaktywne (adnotacje...) w oryginalnych dokumentach (a nawet chcą się ich pozbyć). W takim przypadku należy użyć rozwiązania opartego na klasie PdfWriter.

Szczegóły znajdziesz w rozdziale 6 (szczególnie w sekcji 6.4) iText w działaniu - wydanie 2 . Przykładowy kod Javy można uzyskać tutaj , A wersje C# ' ified tutaj .

Prosty próbka z użyciem PdfCopy to Konkatenat.java / Konkatenat.cs . Centralny fragment kodu to:

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();
}

Tutaj pdf może być zdefiniowany jako List<byte[]> zawierający bezpośrednio dokumenty źródłowe (odpowiednie dla przypadku łączenia dokumentów pośrednich w pamięci) lub jako List<String> zawierający nazwy plików dokumentów źródłowych (odpowiednie, jeśli łączysz dokumenty z dysku).

Przegląd na końcu przywołanego rozdziału podsumowuje użycie klasy wymienione:

  • PdfCopy: kopiuje strony z jednego lub więcej istniejących dokumentów PDF. Główne wady: PdfCopy nie wykrywa redundantnej zawartości i zawodzi podczas łączenia formularzy.

  • PdfCopyFields: umieszcza pola różnych form w jednym formularzu. Może być stosowany w celu uniknięcia problemów z polami formularza podczas łączenia formularzy za pomocą PdfCopy. Użycie pamięci może być problemem.

  • PdfSmartCopy: kopiuje strony z jednego lub więcej istniejących plików PDF dokumenty. {[11] } jest w stanie wykryć redundantną zawartość, ale potrzebuje więcej pamięci i procesora niż PdfCopy.

  • PdfWriter: generuje dokumenty PDF od podstaw. Może importować strony z innych dokumentów PDF. Głównym minusem jest to, że wszystkie interaktywne funkcje importowanej strony (adnotacje, zakładki, pola itp.) są tracone w procesie.

 48
Author: mkl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-11 09:39:24

Używałem iTextsharp z c# do łączenia plików pdf. To jest kod, którego użyłem.

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;
    }
}
 7
Author: Sajitha Nilan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-02 02:45:07

Oto kod, który wyciągnąłem ze starego projektu, który miałem. Była to aplikacja internetowa, ale używałem iTextSharp do łączenia plików pdf, a następnie ich drukowania.

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;
        }
    }
Nie napisałem tego, ale wprowadziłem pewne modyfikacje. Nie pamiętam, gdzie go znalazłem. Po połączeniu plików PDF wywołałbym tę metodę, aby wstawić javascript, aby otworzyć okno dialogowe drukowania po otwarciu pliku PDF. Jeśli zmienisz bSilent na true, powinien on drukować cicho na domyślnej drukarce.
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;
}

Nie wiem, jak dobrze powyższy kod jest napisany, ponieważ wyciągnąłem go z innego miejsca i w ogóle nie pracowałem dogłębnie z iTextSharp, ale wiem, że to działało przy scalaniu plików PDF, które generowałem w czasie wykonywania.

 4
Author: DSlagle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-10 19:08:18

Testowane z 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;
        }
    }
 3
Author: Nina,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-06 13:25:31

Aby uniknąć problemów z pamięcią, użyłem strumienia plików zamiast strumienia pamięci(wymienionego w wyjątku iTextSharp poza pamięcią Scalanie wielu plików pdf) do scalania plików pdf:

        var parentDirectory = Directory.GetParent(SelectedDocuments[0].FilePath);
        var savePath = parentDirectory + "\\MergedDocument.pdf";

        using (var fs = new FileStream(savePath, FileMode.Create))
        {
            using (var document = new Document())
            {
                using (var pdfCopy = new PdfCopy(document, fs))
                {
                    document.Open();
                    for (var i = 0; i < SelectedDocuments.Count; i++)
                    {
                        using (var pdfReader = new PdfReader(SelectedDocuments[i].FilePath))
                        {
                            for (var page = 0; page < pdfReader.NumberOfPages;)
                            {
                                pdfCopy.AddPage(pdfCopy.GetImportedPage(pdfReader, ++page));
                            }
                        }
                    }
                }
            }
        }
 2
Author: Murat Aykanat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:14
****/*For Multiple PDF Print..!!*/****

<button type="button" id="btnPrintMultiplePdf" runat="server" class="btn btn-primary btn-border btn-sm"
                                                                onserverclick="btnPrintMultiplePdf_click">
                                                                <i class="fa fa-file-pdf-o"></i>Print Multiple pdf</button>

protected void btnPrintMultiplePdf_click(object sender, EventArgs e)
    {
        if (ValidateForMultiplePDF() == true)
        {
            #region Declare Temp Variables..!!
            CheckBox chkList = new CheckBox();
            HiddenField HidNo = new HiddenField();

            string Multi_fofile, Multi_listfile;
            Multi_fofile = Multi_listfile = "";
            Multi_fofile = Server.MapPath("PDFRNew");
            #endregion

            for (int i = 0; i < grdRnew.Rows.Count; i++)
            {
                #region Find Grd Controls..!!
                CheckBox Chk_One = (CheckBox)grdRnew.Rows[i].FindControl("chkOne");
                Label lbl_Year = (Label)grdRnew.Rows[i].FindControl("lblYear");
                Label lbl_No = (Label)grdRnew.Rows[i].FindControl("lblCode");
                #endregion

                if (Chk_One.Checked == true)
                {
                    HidNo .Value = llbl_No .Text.Trim()+ lbl_Year .Text;

                    if (File.Exists(Multi_fofile + "\\" + HidNo.Value.ToString() + ".pdf"))
                    {
                        #region Get Multiple Files Name And Paths..!!
                        if (Multi_listfile != "")
                        {
                            Multi_listfile = Multi_listfile + ",";
                        }
                        Multi_listfile = Multi_listfile + Multi_fofile + "\\" + HidNo.Value.ToString() + ".pdf";

                        #endregion
                    }
                }
            }

            #region For Generate Multiple Pdf..!!
            if (Multi_listfile != "")
            {
                String[] Multifiles = Multi_listfile.Split(',');
                string DestinationFile = Server.MapPath("PDFRNew") + "\\Multiple.Pdf";
                MergeFiles(DestinationFile, Multifiles);

                Response.ContentType = "pdf";
                Response.AddHeader("Content-Disposition", "attachment;filename=\"" + DestinationFile + "\"");
                Response.TransmitFile(DestinationFile);
                Response.End();
            }
            else
            {

            }
            #endregion
        }
    }

    private void MergeFiles(string DestinationFile, string[] SourceFiles)
    {
        try
        {
            int f = 0;
            /**we create a reader for a certain Document**/
            PdfReader reader = new PdfReader(SourceFiles[f]);
            /**we retrieve the total number of pages**/
            int n = reader.NumberOfPages;
            /**Console.WriteLine("There are " + n + " pages in the original file.")**/
            /**Step 1: creation of a document-object**/
            Document document = new Document(reader.GetPageSizeWithRotation(1));
            /**Step 2: we create a writer that listens to the Document**/
            PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(DestinationFile, FileMode.Create));
            /**Step 3: we open the Document**/
            document.Open();
            PdfContentByte cb = writer.DirectContent;
            PdfImportedPage page;
            int rotation;
            /**Step 4: We Add Content**/
            while (f < SourceFiles.Length)
            {
                int i = 0;
                while (i < n)
                {
                    i++;
                    document.SetPageSize(reader.GetPageSizeWithRotation(i));
                    document.NewPage();
                    page = writer.GetImportedPage(reader, i);
                    rotation = reader.GetPageRotation(i);
                    if (rotation == 90 || rotation == 270)
                    {
                        cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
                    }
                    else
                    {
                        cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
                    }
                    /**Console.WriteLine("Processed page " + i)**/
                }
                f++;
                if (f < SourceFiles.Length)
                {
                    reader = new PdfReader(SourceFiles[f]);
                    /**we retrieve the total number of pages**/
                    n = reader.NumberOfPages;
                    /**Console.WriteLine("There are"+n+"pages in the original file.")**/
                }
            }
            /**Step 5: we Close the Document**/
            document.Close();
        }
        catch (Exception e)
        {
            string strOb = e.Message;
        }
    }

    private bool ValidateForMultiplePDF()
    {
        bool chkList = false;

        foreach (GridViewRow gvr in grdRnew.Rows)
        {
            CheckBox Chk_One = (CheckBox)gvr.FindControl("ChkSelectOne");
            if (Chk_One.Checked == true)
            {
                chkList = true;
            }
        }
        if (chkList == false)
        {
            divStatusMsg.Style.Add("display", "");
            divStatusMsg.Attributes.Add("class", "alert alert-danger alert-dismissable");
            divStatusMsg.InnerText = "ERROR !!...Please Check At Least On CheckBox.";
            grdRnew.Focus();
            set_timeout();
            return false;
        }
        return true;
    }
 0
Author: JIYAUL MUSTAPHA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-27 11:12:55