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.