如何将.pdf和.jpg文件合并为一个pdf文件

4

磁盘上有两个文件,一个是.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);
1个回答

4

鉴于您一直遇到这个问题,我将给您一个较长的答案,希望能帮助您。

首先,我没有访问ASP.Net服务器,因此我正在从桌面上的文件夹运行所有内容。因此,您将看到我从Environment.GetFolderPath(Environment.SpecialFolder.Desktop)开始读写,而不是相对路径。我假设您稍后可以更换您自己的路径。

其次,(虽然并不重要),我没有SSRS,所以我创建了一个“帮助器”方法,为我生成虚拟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都是常用的方法。我鼓励您阅读官方iText/iTextSharp书籍,或者至少阅读免费的第6章,与现有PDF一起工作,该章节详细介绍了这一点。在下面的代码中,我使用PdfSmartCopy,并将每个图像转换为PDF再导入。可能有更好的方法,但我不确定是否可以一次性完成。Bruno比我更清楚。但下面的代码可行。

有关正在进行的详细信息,请参见各个代码注释。

//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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接