【问题标题】:How to merge .pdf and .jpg file in one pdf如何将 .pdf 和 .jpg 文件合并到一个 pdf 中
【发布时间】:2015-09-10 17:53:07
【问题描述】:

磁盘上有两个文件 .jpg 和 .pdf,我需要读取这两个文件并将它们添加到新的 pdf 并发送到浏览器以便可以下载。

新的 pdf 文件只包含 pdf 内容而不包含 jpeg 文件图像。

          memoryStream myMemoryStream = new MemoryStream();

        //----pdf file--------------

        iTextSharp.text.pdf.PdfCopy writer2 = new iTextSharp.text.pdf.PdfCopy(doc, myMemoryStream);

        doc.Open();

        iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(imagepath + "/30244.pdf");
        reader.ConsolidateNamedDestinations();

        for (int i = 1; i <= reader.NumberOfPages; i++) {
            iTextSharp.text.pdf.PdfImportedPage page = writer2.GetImportedPage(reader, i);
            writer2.AddPage(page);
        }

        iTextSharp.text.pdf.PRAcroForm form = reader.AcroForm;
        if (form != null) {
            writer2.CopyAcroForm(reader);
        }

        //-----------------jpeg file-------------------------------------
        MemoryStream myMemoryStream2 = new MemoryStream();
        System.Drawing.Image image = System.Drawing.Image.FromFile(imagepath + "/Vouchers.jpg");
        iTextSharp.text.Document doc2 = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4);
        iTextSharp.text.pdf.PdfWriter.GetInstance(doc2, myMemoryStream2);
        doc2.Open();
        iTextSharp.text.Image pdfImage = iTextSharp.text.Image.GetInstance(image, System.Drawing.Imaging.ImageFormat.Jpeg);

       doc2.Add(pdfImage);

       doc2.close();
       doc.close();

        byte[] content = myMemoryStream.ToArray;

        Response.ContentType = "application/pdf";
        Response.AppendHeader("Content-Disposition", "attachment; filename=LeftCorner568.pdf");
        Response.BinaryWrite(content);

【问题讨论】:

    标签: c# asp.net pdf itextsharp


    【解决方案1】:

    由于您已经为此困扰了一段时间,因此我将为您提供一个冗长的答案,希望对您有所帮助。

    首先,我无法访问 ASP.Net 服务器,因此我从桌面上的文件夹运行所有内容。因此,您将看到我在Environment.GetFolderPath(Environment.SpecialFolder.Desktop) 工作,而不是从相对路径读取和写入。我假设您以后可以交换路径。

    第二,(这并不重要)我没有 SSRS,所以我创建了一个辅助方法,该方法可以为我制作一个假 PDF,然后将 PDF 作为字节数组返回:

    /// <summary>
    /// Create a fake SSRS report
    /// </summary>
    /// <returns>A valid PDF stored as a byte array</returns>
    private Byte[] getSSRSPdfAsByteArray() {
        using (var ms = new System.IO.MemoryStream()) {
            using (var doc = new Document()) {
                using (var writer = PdfWriter.GetInstance(doc, ms)) {
                    doc.Open();
                    doc.Add(new Paragraph("This is my SSRS report"));
                    doc.Close();
                }
            }
    
            return ms.ToArray();
        }
    }
    

    第三,为了让我们在同一个页面上并有一些东西可以使用,我创建了两个额外的帮助方法来生成一些示例图像和 PDF:

    /// <summary>
    /// Create sample images in the folder provided
    /// </summary>
    /// <param name="count">The number of images to create</param>
    /// <param name="workingFolder">The folder to create images in</param>
    private void createSampleImages(int count, string workingFolder) {
        var random = new Random();
        for (var i = 0; i < count; i++) {
            using (var bmp = new System.Drawing.Bitmap(200, 200)) {
                using (var g = System.Drawing.Graphics.FromImage(bmp)) {
                    g.Clear(Color.FromArgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255)));
                }
                bmp.Save(System.IO.Path.Combine(workingFolder, string.Format("Image_{0}.jpg", i)));
            }
        }
    }
    
    /// <summary>
    /// Create sample PDFs in the folder provided
    /// </summary>
    /// <param name="count">The number of PDFs to create</param>
    /// <param name="workingFolder">The folder to create PDFs in</param>
    private void createSamplePDFs(int count, string workingFolder) {
        var random = new Random();
        for (var i = 0; i < count; i++) {
            using (var ms = new System.IO.MemoryStream()) {
                using (var doc = new Document()) {
                    using (var writer = PdfWriter.GetInstance(doc, ms)) {
                        doc.Open();
                        var pageCount = random.Next(1, 10);
                        for (var j = 0; j < pageCount; j++) {
                            doc.NewPage();
                            doc.Add(new Paragraph(String.Format("This is page {0} of document {1}", j, i)));
                        }
                        doc.Close();
                    }
                }
    
                System.IO.File.WriteAllBytes(System.IO.Path.Combine(workingFolder, string.Format("File_{0}.pdf", i)), ms.ToArray());
            }
        }
    }
    

    重申一下,您显然不需要这三个辅助方法,它们只是为了让您和我有一组共同的文件可供使用。这些辅助方法也有意不注释。

    第四,在下面代码的末尾,我将最终的 PDF 存储到一个名为 finalFileBytes 的字节数组中,然后将其写入磁盘。再一次,我在桌面上工作,所以你可以在这里使用Response.BinaryWrite(finalFileBytes)

    第五,有不同的方式来合并和合并文件。 PdfCopyPdfSmartCopyPdfStamper都是常用的。我鼓励您阅读official iText/iTextSharp book 或至少阅读免费的第 6 章,使用现有 PDF,其中详细介绍了这一点。在下面的代码中,我使用了PdfSmartCopy,并且在导入之前将每个图像转换为 PDF。可能有更好的方法,但我不确定您是否可以一次完成所有操作。布鲁诺会比我更清楚。但下面的工作。

    查看各个代码 cmets 了解更多详情。

    //The folder that all of our work will be done in
    var workingFolder = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Pdf Test");
    
    //This is the final PDF that we'll create for testing purposes
    var finalPDF = System.IO.Path.Combine(workingFolder, "test.pdf");
    
    //Create our working directory if it doesn't exist already
    System.IO.Directory.CreateDirectory(workingFolder);
    
    //Create sample PDFs and images
    createSampleImages(10, workingFolder);
    createSamplePDFs(10, workingFolder);
    
    //Create our sample SSRS PDF byte array
    var SSRS_Bytes = getSSRSPdfAsByteArray();
    
    //This variable will eventually hold our combined PDF as a byte array
    Byte[] finalFileBytes;
    
    //Write everything to a MemoryStream
    using (var finalFile = new System.IO.MemoryStream()) {
    
        //Create a generic Document
        using (var doc = new Document()) {
    
            //Use PdfSmartCopy to intelligently merge files
            using (var copy = new PdfSmartCopy(doc, finalFile)) {
    
                //Open our document for writing
                doc.Open();
    
                //#1 - Import the SSRS report
    
                //Bind a reader to our SSRS report
                using (var reader = new PdfReader(SSRS_Bytes)) {
    
                    //Loop through each page
                    for (var i = 1; i <= reader.NumberOfPages; i++) {
    
                        //Add the imported page to our final document
                        copy.AddPage(copy.GetImportedPage(reader, i));
                    }
                }
    
                //#2 - Image the images
    
                //Loop through each image in our working directory
                foreach (var f in System.IO.Directory.EnumerateFiles(workingFolder, "*.jpg", SearchOption.TopDirectoryOnly)) {
    
                    //There's different ways to do this and it depends on what exactly "add an image to a PDF" really means
                    //Below we add each individual image to a PDF and then merge that PDF into the main PDF
                    //This could be optimized greatly
    
                    //From https://alandjackson.wordpress.com/2013/09/27/convert-an-image-to-a-pdf-in-c-using-itextsharp/
    
                    //Get the size of the current image
                    iTextSharp.text.Rectangle pageSize = null;
                    using (var srcImage = new Bitmap(f)) {
                        pageSize = new iTextSharp.text.Rectangle(0, 0, srcImage.Width, srcImage.Height);
                    }
    
                    //Will eventually hold the PDF with the image as a byte array
                    Byte[] imageBytes;
    
                    //Simple image to PDF
                    using (var m = new MemoryStream()) {
                        using (var d = new Document(pageSize, 0, 0, 0, 0)) {
                            using (var w = PdfWriter.GetInstance(d, m)) {
                                d.Open();
                                d.Add(iTextSharp.text.Image.GetInstance(f));
                                d.Close();
                            }
                        }
    
                        //Grab the bytes before closing out the stream
                        imageBytes = m.ToArray();
                    }
    
                    //Now merge using the same merge code as #1
                    using (var reader = new PdfReader(imageBytes)) {
                        for (var i = 1; i <= reader.NumberOfPages; i++) {
                            copy.AddPage(copy.GetImportedPage(reader, i));
                        }
                    }
                }
    
                //#3 - Merge additional PDF
    
                //Look for each PDF in our working directory
                foreach (var f in System.IO.Directory.EnumerateFiles(workingFolder, "*.pdf", SearchOption.TopDirectoryOnly)) {
    
                    //Because I'm writing samples files to disk but not cleaning up afterwards
                    //I want to avoid adding my output file as an input file
                    if (f == finalPDF) {
                        continue;
                    }
    
                    //Now merge using the same merge code as #1
                    using (var reader = new PdfReader(f)) {
                        for (var i = 1; i <= reader.NumberOfPages; i++) {
                            copy.AddPage(copy.GetImportedPage(reader, i));
                        }
                    }
                }
    
                doc.Close();
            }
        }
    
        //Grab the bytes before closing the stream
        finalFileBytes = finalFile.ToArray();
    }
    
    //At this point finalFileBytes holds a byte array of a PDF
    //that contains the SSRS PDF, the sample images and the
    //sample PDFs. For demonstration purposes I'm just writing to
    //disk but this could be written to the HTTP stream
    //using Response.BinaryWrite()
    
    System.IO.File.WriteAllBytes(finalPDF, finalFileBytes);
    

    【讨论】:

      猜你喜欢
      • 2015-10-18
      • 2014-10-30
      • 1970-01-01
      • 2013-06-10
      • 2011-06-18
      • 2016-04-27
      • 1970-01-01
      • 2014-11-16
      • 1970-01-01
      相关资源
      最近更新 更多