Using itextpdf to solve the problem of PDF merging

  • 2021-10-24 22:55:19
  • OfStack

itextpdf solves the problem of PDF merging

This article was documented when I addressed a requirement for PDF display during project development.

The requirement is that two PDF need to be merged, one PDF is formed in the background according to the information of the database (PDF that does not actually exist), and the other is PDF file saved on disk (this PDF file will be obtained from the cloud later).

As a rookie of Java, this problem was solved for several days, and it was solved under the guidance of leader. Make a record of 1 key code here.

The project mainly contains the following keywords: (I won't explain it in detail, mainly using these)

-Spring, MVC, Spring, Hibernate

- Maven

- Java

- itextpdf

- MySQL

-JavaWeb correlation

The first is the dependency of itextpdf


<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.10</version>
</dependency>

How to generate an PDF in the background

Baidu has many solutions to this problem, because I need to splice the generated PDF with the existing PDF, so I tried many solutions and decided to turn this document into a byte array in the form of a document, and then read the stream into PDF with itextpdf.

Generate part of the code for PDF:


import java.io.ByteArrayOutputStream;
import com.model.User;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
public class ReportKit {
     public static byte[] createReport(User user) throws Exception {
               ByteArrayOutputStream ba = new ByteArrayOutputStream();
               Document doc = new Document();// Create 1 A document Object 
               PdfWriter writer = PdfWriter.getInstance(doc, ba);// This PdfWriter Meeting 1 Write straight to the document. 
              doc.open();// Open a document 
              BaseFont bfChinese = BaseFont.createFont("c://windows//fonts//msyh.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
              com.itextpdf.text.Font FontChinese18 = new com.itextpdf.text.Font(bfChinese, 18, com.itextpdf.text.Font.BOLD);
              com.itextpdf.text.Font FontChinese12 = new com.itextpdf.text.Font(bfChinese, 12, com.itextpdf.text.Font.NORMAL);
              com.itextpdf.text.Font FontChinese11 = new com.itextpdf.text.Font(bfChinese, 11, com.itextpdf.text.Font.ITALIC);
              Font fontChinese =  new  Font(bfChinese  ,  12 , Font.NORMAL, BaseColor.BLACK);
              Paragraph pf = new Paragraph("");
              // Add a blank line 
              Paragraph blankRow1 = new Paragraph(24f," ",FontChinese18);
              doc.add(blankRow1);
              //table2
              PdfPTable table25 = new PdfPTable(2);
              // Set the width ratio of each column 
              int width21[] = {2,98};
              table25.setWidths(width21);
              table25.getDefaultCell().setBorder(0);
              PdfPCell cell25 = new PdfPCell(new Paragraph(" This is 1 Reports ",FontChinese18));
              cell25.setBorder(0);
              table25.addCell("");
              table25.addCell(cell25);
              doc.add(table25);
              Paragraph blankRow3 = new Paragraph(18f, "Report ", FontChinese11);
              blankRow3.setAlignment(PdfContentByte.ALIGN_RIGHT);
              doc.add(blankRow3);        
              BaseColor lightGrey = new BaseColor(0xCC,0xCC,0xCC);
              PdfPTable table8 = new PdfPTable(6);
            // Settings table The width of is 100%
            table8.setWidthPercentage(100);
            // Set the width of different columns 
            float[] columnWidths = {1.6f, 1.6f, 1.6f, 1.6f, 1.6f, 1.6f};
            table8.setWidths(columnWidths);
              PdfPCell cell1 = new PdfPCell(new Paragraph(" User name ",FontChinese12));
            PdfPCell cell2 = new PdfPCell(new Paragraph(" Date of Birth ",FontChinese12));
            PdfPCell cell3 = new PdfPCell(new Paragraph(" Gender ",FontChinese12));
            PdfPCell cell4 = new PdfPCell(new Paragraph(" Height ",FontChinese12));
            PdfPCell cell5 = new PdfPCell(new Paragraph(" Weight ",FontChinese12));
            PdfPCell cell6 = new PdfPCell(new Paragraph(" Region ",FontChinese12));
            PdfPCell cell7 = new PdfPCell(new Paragraph(user.getAccessname(),FontChinese12));
            PdfPCell cell8 = new PdfPCell(new Paragraph(user.getBirthday(),FontChinese12));
            PdfPCell cell9 = new PdfPCell(new Paragraph(sex,FontChinese12));
            PdfPCell cell10 = new PdfPCell(new Paragraph(String.valueOf(user.getHeight()),FontChinese12));
            PdfPCell cell11 = new PdfPCell(new Paragraph(String.valueOf(user.getWeight()),FontChinese12));
            PdfPCell cell12 = new PdfPCell(new Paragraph(user.getArea_name(),FontChinese12));
            // Table height 
            cell1.setFixedHeight(30);
            cell2.setFixedHeight(30);
            cell3.setFixedHeight(30);
            cell4.setFixedHeight(30);
            cell5.setFixedHeight(30);
            cell6.setFixedHeight(30);
            cell7.setFixedHeight(30);
            cell8.setFixedHeight(30);
            cell9.setFixedHeight(30);
            cell10.setFixedHeight(30);
            cell11.setFixedHeight(30);
            cell12.setFixedHeight(30);
            // Horizontal center 
           cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell2.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell3.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell4.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell5.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell6.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell7.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell8.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell9.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell10.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell11.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell12.setHorizontalAlignment(Element.ALIGN_CENTER);
            // Vertical center 
            cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell3.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell4.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell5.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell6.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell7.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell8.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell9.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell10.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell11.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell12.setVerticalAlignment(Element.ALIGN_MIDDLE);
            // Border color 
            cell1.setBorderColor(lightGrey);
            cell2.setBorderColor(lightGrey);
            cell3.setBorderColor(lightGrey);
            cell4.setBorderColor(lightGrey);
            cell5.setBorderColor(lightGrey);
            cell6.setBorderColor(lightGrey);
            cell7.setBorderColor(lightGrey);
            cell8.setBorderColor(lightGrey);
            cell9.setBorderColor(lightGrey);
            cell10.setBorderColor(lightGrey);
            cell11.setBorderColor(lightGrey);
            cell12.setBorderColor(lightGrey);
            table8.addCell(cell1);
            table8.addCell(cell2);
            table8.addCell(cell3);
            table8.addCell(cell4);
            table8.addCell(cell5);
            table8.addCell(cell6);
            table8.addCell(cell7);
            table8.addCell(cell8);
            table8.addCell(cell9);
            table8.addCell(cell10);
            table8.addCell(cell11);
            table8.addCell(cell12);        
            doc.add(table8);
            doc.close();// (If you open a document, remember to close it.) 
            writer.close();
            byte[] bytes = ba.toByteArray();          
            return bytes;
     }
}

document to edit documents, really disgusting, time-consuming and laborious, typesetting is not easy to tune, if you can have a better way, I hope you can tell me.

At this point, by calling this method, you can get the byte array of this document.

Next, we will start splicing PDF. Because it is implemented in combination with front-end pages. Therefore, this method was completed by me in controller.


// Pay attention to the produces , " application/pdf ", it is precisely because this is set up , So that the entire method wraps the document with the PDF Returns to the page in the format of. 
@RequestMapping(value = "/newPdf/{report_name}", produces = "application/pdf;charset=UTF-8")
    public void updateReport(Model model, @PathVariable String report_name, HttpServletRequest request,
            HttpServletResponse response,HttpSession session) {
        try {
            User user = (User) session.getAttribute("user");
            // This is saved to the user after logging in session User information in (you can replace this with other objects) 
            if(user==null){
                return ;
            }
            PdfReader reader1 =null;
            try {
                //  Call the build just written PDF Gets this byte array. 
                byte[] pdfUserByte=ReportKit.createReport(user);
                if(pdfUserByte==null||pdfUserByte.length==0){
                    return;
                }
                // Use pdfReader To read the byte array, where the document information is read into 
                 reader1 = new PdfReader(pdfUserByte);
            } catch (Exception e) {
                System.out.println(e.getMessage());
                return ;
            }
            if(reader1==null) return;
            // No. 1 2 A PDF Read of 
            PdfReader reader2;
            //  Reported PDF
            reader2 = new PdfReader("C:\\Users\\Administrator\\Desktop\\report.pdf");
            Document document = new Document();
            PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
            document.open();
            PdfContentByte cb = writer.getDirectContent();
            int totalPages = 0;
            totalPages += reader1.getNumberOfPages();
            totalPages += reader2.getNumberOfPages();
            java.util.List<PdfReader> readers = new ArrayList<PdfReader>();
            readers.add(reader1);
            readers.add(reader2);
            int pageOfCurrentReaderPDF = 0;
            Iterator<PdfReader> iteratorPDFReader = readers.iterator();
            // Loop through the PDF files and add to the output.
            while (iteratorPDFReader.hasNext()) {
                PdfReader pdfReader = iteratorPDFReader.next();
                // Create a new page in the target for each source page.
                while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
                    document.newPage();// Create a new 1 Page 
                    pageOfCurrentReaderPDF++;
                    PdfImportedPage page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
                    cb.addTemplate(page, 0, 0);
                }
                pageOfCurrentReaderPDF = 0;
            }
            document.close();
            writer.close();
        } catch (IOException | DocumentException e) {
            e.printStackTrace();
        }
    }

For how to preview the PDF on the page, I used the object tag to get it.

Partial fragments on jsp


    <div class="pdf" id="pdf" ><!-- pdf -->
    <object type="application/pdf" data="http://localhost:8080/project/newPdf/${report.report_name}" id="review" style="width:1100px; height:1000px; margin-top:25px; margin-left:50px" > 
    </object>
    </div>

Tag is a good realization of PDF preview function, if it is PDF of URL, data directly input URL, PDF can be previewed in the page, feeling pretty easy to use.

iText merges PDF file to report error

Error is reported when merging using iText operation PDF:

com.lowagie.text.exceptions.BadPasswordException: PdfReader not opened with owner password


public static PdfReader unlockPdf(PdfReader pdfReader) {
     if (pdfReader == null) {
      return pdfReader;
     }
     try {
      java.lang.reflect.Field f = pdfReader.getClass().getDeclaredField("encrypted");
      f.setAccessible(true);
      f.set(pdfReader, false);
     } catch (Exception e) {
       // ignore
     }
     return pdfReader;
    }

This problem can be solved by using the above method for reader.


Related articles: