Recently, I got a requirement, which needs to export PDF documents. There are many ways to realize it on the market. After testing and research, I decided to use itext5 to realize it. If I don't say much, I'll do what I say.
1. Dependent import
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13.1</version> </dependency> <!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version> </dependency>
Here's the description: the above dependency is mainly to achieve PDF generation, and the following dependency is related to Chinese font;
2.PDF table export implementation
1. export PDF
// 1. Open the document and set basic properties Document document = new Document(); // 2. Set request header and encode file name response.setContentType("application/pdf;charset=UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode("" + recordDto.getTitle() + ".pdf", "UTF-8")); // 3. Write out the pdf instance to the browser through the stream PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
So far, the export PDF has been implemented, but there is nothing in the PDF. Understand this, and the next step is to "feed" the document (the response here is HttpServletResponse).
2. Page beautification
// The wirter here is the writer above writer.setViewerPreferences(PdfWriter.PageModeUseThumbs); writer.setPageSize(PageSize.A4);
The display thumbnail of the document and the size of the document are set as A4;
3. Chinese font setting
public static Font getPdfChineseFont() throws Exception { BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font fontChinese = new Font(bfChinese, 12, Font.NORMAL); fontChinese.setColor(BaseColor.BLACK); fontChinese.setSize(11); return fontChinese; }
This method sets the Chinese font style. Interested students can try other styles, such as: font color, size, font can be modified;
4. Output form content to document
// Open document first document.open(); // Add table data to the document private static void printBasicInfo(ShopApplyRecordDto recordDto, Document document, Font font) throws DocumentException { // Data in tables Object[][] basicDatas = { {"Title","xxx Apply", "Approval number","1234"}, {"Applicant","Xiao Ming", "Application shop","xxx Market"}, {"Date of application","2020/1/16", "Approval result","Agree!")}}; // Width of each cell float[] widthss = {50, 200, 50, 200}; // Create a table with four cell s per row PdfPTable basicTable = new PdfPTable(widthss); // Outer loop table row for (int i = 0; i < basicDatas.length; i++) { // Inner loop each row of specific data for (int j = 0; j < basicDatas[i].length; j++) { // Create a new cell PdfPCell cell = new PdfPCell(); // This method is to uniformly set the table and cell styles. The following will be written setTableStyle(basicTable, cell); // Format of data to be filled in cell Paragraph paragraph = new Paragraph(StrUtil.toString(basicDatas[i][j]), font); // Set cell value cell.setPhrase(paragraph); // Add cell s to the table basicTable.addCell(cell); } } // Add table to document document.add(basicTable); } // Close document at end document.close();
Now the exported PDF has tables like this:
Of course, your style will be ugly. Next, let's set the style.
5. Table and cell style settings
public static void setTableStyle(PdfPTable table, PdfPCell cell) { // Set table style table.setLockedWidth(true); table.setTotalWidth(500); table.setHorizontalAlignment(Element.ALIGN_LEFT); // Set cell style cell.setMinimumHeight(35); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); cell.setBackgroundColor(BaseColor.WHITE); cell.setBorder(0); cell.setBorderWidthTop(0.1f); cell.setBorderWidthBottom(0.1f); cell.setBorderWidthLeft(0.1f); cell.setBorderWidthRight(0.1f); cell.setBorderColorBottom(BaseColor.BLACK); cell.setBorderColorLeft(BaseColor.BLACK); cell.setBorderColorRight(BaseColor.BLACK); cell.setBorderColorTop(BaseColor.BLACK); cell.setPadding(3); }
api methods are still relatively easy to understand. I won't go into details here. If you don't understand, you can try your own settings to make your own style.
6. Setting of header and page number
This shows that the api of itext2 and itext5 are quite different. There is a special HeaderFooter class to set the style in version 2. There is no such class in version 5. Instead, there is an event processing class such as PdfPageEventHelper. Please don't confuse these two versions of api. They are incompatible with each other;
First, write a subclass of PdfPageEventHelper to print the header page number:
public class HeaderFooter extends PdfPageEventHelper { // Here are business-related attributes that can be ignored private ShopApplyRecordDto recordDto; private SysUserInfo userInfo; // In most cases, the header value is dynamic. Here, parameters can be passed during initialization public HeaderFooter(ShopApplyRecordDto recordDto, SysUserInfo userInfo) { this.recordDto = recordDto; this.userInfo = userInfo; } public HeaderFooter() { } public ShopApplyRecordDto getRecordDto() { return recordDto; } public void setRecordDto(ShopApplyRecordDto recordDto) { this.recordDto = recordDto; } public SysUserInfo getUserInfo() { return userInfo; } public void setUserInfo(SysUserInfo userInfo) { this.userInfo = userInfo; } // This method is the key to the implementation of header and page number: it means that the method will be executed every time the page ends @Override public void onEndPage(PdfWriter writer, Document document) { Font font = null; try { font = getPdfChineseFont(); } catch (Exception e) { e.printStackTrace(); } SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm"); // Set header: in this case, you can use space to realize the header of three positions in the middle left and right. In fact, you can write three. You can control the location of the header through element. Align? Left () / document. Top (), which can set the specific location of the header similar to the up and down adjustment of html. You can try more ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, new Phrase("Project:" + recordDto.getMallName() + " Printing time:" + format.format(new Date()) + " Printer:" + userInfo.getUserName(), font), document.left(), document.top() + 3, 0); // Get a box called "art" Rectangle rect = writer.getBoxSize("art"); // Set page number: the page number position here has been set, and you can use it directly. As for the page number realization of 1 / 20 effect, it is very complicated. If you need it, please Baidu / Google yourself ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, new Phrase(String.format("%d", writer.getPageNumber())), (rect.getLeft() + rect.getRight()) / 2, rect.getBottom() - 18, 0); } public static Font getPdfChineseFont() throws Exception { BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font fontChinese = new Font(bfChinese, 12, Font.NORMAL); fontChinese.setColor(BaseColor.BLACK); fontChinese.setSize(11); return fontChinese; } }
Next, simply set our HeaderFooter to the PdfWriter object:
// Create a new HeaderFooter and pass the required parameters HeaderFooter headerFooter = new HeaderFooter(recordDto, userInfo); // Create a new box Rectangle rect = new Rectangle(36, 54, 559, 788); // Set the name to "art". This is the box that get s on it writer.setBoxSize("art", rect); writer.setPageEvent(headerFooter); // This can set the margin of the content document.setMargins(45f, 45f, 65f, 50f);
7. Effect display
8. summary
OK, it's fully realized by printing PDF documents here. In fact, itext5 has many functions, such as text, pictures and links. If you need to go to the official documents, you can also leave a message to ask me what's wrong with my first blog. I hope you can put it forward in the message, so that I can correct it in time, so as not to make mistakes.