Java Itext 生成PDF文件
利用Java Itext生成PDF文件并导出,实现效果如下:
PDFUtil.java
package com.jeeplus.modules.order.util; import java.io.OutputStream; import java.math.BigDecimal; import java.net.URL; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.servlet.http.HttpServletResponse; import com.itextpdf.text.BaseColor; import com.itextpdf.text.Chunk; import com.itextpdf.text.Document; import com.itextpdf.text.Element; import com.itextpdf.text.Font; import com.itextpdf.text.Image; import com.itextpdf.text.PageSize; import com.itextpdf.text.Paragraph; import com.itextpdf.text.Phrase; 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.PdfWriter; import com.jeeplus.common.utils.Encodes; import com.jeeplus.common.utils.StringUtils; import com.jeeplus.modules.order.entity.OrderHeader; import com.jeeplus.modules.order.entity.OrderLine; import com.jeeplus.modules.order.service.PDFService; import com.jeeplus.modules.sys.utils.UserUtils; public class PDFUtil { /** * * @param exhibitionName 展会名称 * @param orders 订单 * @param REMITTANCE_UNIT 收款单位 * @param REMITTANCE_BANK 收款银行 * @param REMITTANCE_ACCOUNT 收款账号 * @param SEAL_PICTURE_NAME 印章名称默认为深圳中智兴 * @param payUrl 系统网址 * @param response * @throws Exception author:xiaofei.xian 日期:2018年5月30日 上午11:29:57 */ public static void createPDF(String exhibitionName, List<OrderHeader> orders, String REMITTANCE_UNIT, String REMITTANCE_BANK, String REMITTANCE_ACCOUNT, String SEAL_PICTURE_NAME, String payUrl, HttpServletResponse response) throws Exception { // 生成PDF Document document = new Document(PageSize.A4); BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font fontChinese = new Font(bfChinese, 12, Font.NORMAL); Font fontMoney = new Font(bfChinese, 13, Font.BOLD, BaseColor.RED); Font BlodFont = new Font(bfChinese, 12, Font.BOLD, BaseColor.BLACK); // 写入器 PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream()); // 只读 writer.setEncryption(null, null, PdfWriter.ALLOW_PRINTING, PdfWriter.STANDARD_ENCRYPTION_128); // 通过PDF页面事件模式添加文字水印功能 writer.setPageEvent(new TextWaterMarkPdfPageEvent(REMITTANCE_UNIT)); // 添加页脚功能 document.open(); PdfPTable pdfPTable = new PdfPTable(1); PdfFooterEvent footerTable = new PdfFooterEvent(pdfPTable, payUrl); footerTable.setTableFooter(writer); document.add(pdfPTable); // 添加PDF属性 document.open(); Paragraph pph1 = new Paragraph("预租确认回执", new Font(bfChinese, 20, Font.BOLD, BaseColor.BLACK)); pph1.setAlignment(Element.ALIGN_CENTER); pph1.setSpacingAfter(10); pph1.setSpacingBefore(5); document.add(pph1); // 6列的表. PdfPTable table = new PdfPTable(6); table.setTotalWidth(500); table.setLockedWidth(true); table.setHorizontalAlignment(Element.ALIGN_CENTER); // 第一行 PdfPCell cell1 = new PdfPCell(new Phrase("展会名称:" + exhibitionName, fontChinese)); cell1.setColspan(6); table.addCell(cell1); StringBuffer boothNums = new StringBuffer(); for (OrderHeader orderHeader : orders) { // 获取订单信息 boothNums.append(orderHeader.getExName() + ","); } // 第二行 PdfPCell cell2 = new PdfPCell(new Phrase("展位编号:" + boothNums.toString().subSequence(0, boothNums.length() - 1), fontChinese)); cell2.setColspan(6); table.addCell(cell2); // 第三行 PdfPCell cell3 = new PdfPCell(new Phrase("下单人:" + UserUtils.get(orders.get(0).getCreateBy()).getName(), fontChinese)); cell3.setColspan(6); cell3.setHorizontalAlignment(Element.ALIGN_RIGHT); table.addCell(cell3); // 第四行 PdfPCell cell4_1 = new PdfPCell(new Phrase("名称", fontChinese)); PdfPCell cell4_2 = new PdfPCell(new Phrase("规格", fontChinese)); PdfPCell cell4_3 = new PdfPCell(new Phrase("单价", fontChinese)); PdfPCell cell4_4 = new PdfPCell(new Phrase("押金", fontChinese)); PdfPCell cell4_5 = new PdfPCell(new Phrase("数量", fontChinese)); PdfPCell cell4_6 = new PdfPCell(new Phrase("小计", fontChinese)); table.addCell(cell4_1); table.addCell(cell4_2); table.addCell(cell4_3); table.addCell(cell4_4); table.addCell(cell4_5); table.addCell(cell4_6); BigDecimal total = BigDecimal.ZERO; List<OrderLine> orderLines = new ArrayList<OrderLine>(); for (OrderHeader orderHeader : orders) { orderLines = orderHeader.getOrderLines(); for (OrderLine orderLine : orderLines) { cell4_1 = new PdfPCell(new Phrase(orderLine.getGoodsName(), fontChinese)); cell4_2 = new PdfPCell(new Phrase(orderLine.getSpecifications(), fontChinese)); cell4_3 = new PdfPCell(new Phrase(String.valueOf(orderLine.getUnitPrice()), fontChinese)); DecimalFormat df1 = new DecimalFormat("0.00"); String str = df1.format(orderLine.getForegift().multiply(orderLine.getBuyNum().subtract(orderLine.getEditForegiftPrice()))); cell4_4 = new PdfPCell(new Phrase(str, fontChinese)); cell4_5 = new PdfPCell(new Phrase(String.valueOf(orderLine.getBuyNum()), fontChinese)); cell4_6 = new PdfPCell(new Phrase(String.valueOf((orderLine.getUnitPrice().add(orderLine.getForegift())).multiply(orderLine.getBuyNum()) .subtract(orderLine.getEditFeePrice().subtract(orderLine.getEditForegiftPrice()))), fontChinese)); total = total.add((orderLine.getUnitPrice().add(orderLine.getForegift())).multiply(orderLine.getBuyNum()) .subtract(orderLine.getEditFeePrice().subtract(orderLine.getEditForegiftPrice()))); table.addCell(cell4_1); table.addCell(cell4_2); table.addCell(cell4_3); table.addCell(cell4_4); table.addCell(cell4_5); table.addCell(cell4_6); } } // 第六行 PdfPCell cell6 = new PdfPCell(new Phrase("总计:" + total, fontMoney)); cell6.setColspan(6); table.addCell(cell6); // 第七行 PdfPCell cell7_1 = new PdfPCell(new Phrase("收款单位:", fontChinese)); PdfPCell cell7_2 = new PdfPCell(new Phrase(REMITTANCE_UNIT, fontChinese)); cell7_1.setHorizontalAlignment(Element.ALIGN_LEFT); cell7_2.setHorizontalAlignment(Element.ALIGN_LEFT); cell7_1.setColspan(2); cell7_2.setColspan(4); table.addCell(cell7_1); table.addCell(cell7_2); cell7_1 = new PdfPCell(new Phrase("开户行:", fontChinese)); cell7_2 = new PdfPCell(new Phrase(REMITTANCE_BANK, fontChinese)); cell7_1.setHorizontalAlignment(Element.ALIGN_LEFT); cell7_2.setHorizontalAlignment(Element.ALIGN_LEFT); cell7_1.setColspan(2); cell7_2.setColspan(4); table.addCell(cell7_1); table.addCell(cell7_2); cell7_1 = new PdfPCell(new Phrase("账号:", fontChinese)); cell7_2 = new PdfPCell(new Phrase(REMITTANCE_ACCOUNT, fontMoney)); cell7_1.setHorizontalAlignment(Element.ALIGN_LEFT); cell7_2.setHorizontalAlignment(Element.ALIGN_LEFT); cell7_1.setColspan(2); cell7_2.setColspan(4); table.addCell(cell7_1); table.addCell(cell7_2); // 第十行 PdfPCell cell10 = new PdfPCell(new Phrase(REMITTANCE_UNIT, fontChinese)); cell10.setHorizontalAlignment(Element.ALIGN_RIGHT); cell10.setColspan(6); table.addCell(cell10); document.add(table); // 默认为深圳中智兴 if (StringUtils.isEmpty(SEAL_PICTURE_NAME)) { SEAL_PICTURE_NAME = "zzx_seal.png"; } // 读入并设置印章图片 URL resource = PDFService.class.getResource("/sealimg/" + SEAL_PICTURE_NAME); Image image = Image.getInstance(resource); image.setScaleToFitLineWhenOverflow(true); image.setAlignment(Element.ALIGN_RIGHT); float x = table.getTotalWidth(); float y = 750 - table.getTotalHeight(); while (y < 0) { y = 750 - (table.getTotalHeight() - 750); } image.setAbsolutePosition(x - 60, y); image.scaleAbsolute(100, 100); PdfContentByte pcb = writer.getDirectContentUnder(); pcb.addImage(image); document.add(image); document.add(Chunk.NEWLINE); // 特别提醒 Paragraph paragraphRemark = new Paragraph(); Font remarkFont = new Font(bfChinese, 10, Font.NORMAL); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); paragraphRemark.add(new Chunk("特别提醒:", BlodFont)); paragraphRemark.add(Chunk.NEWLINE); paragraphRemark.add(new Chunk("1.您的汇款识别码为", remarkFont)); paragraphRemark.add(new Chunk(orders.get(0).getRemitCode(), fontMoney)); paragraphRemark.add(new Chunk("。请将此识别码填写到汇款单【附言】栏内(仅填写此识别码),如未填写会影响订单确认时间。", remarkFont)); paragraphRemark.add(Chunk.NEWLINE); paragraphRemark.add(Chunk.NEWLINE); paragraphRemark.add(new Chunk("2.请将待支付款项在", remarkFont)); paragraphRemark.add(new Chunk(sdf.format(orders.get(0).getCancelDate()), fontMoney)); paragraphRemark.add(new Chunk("前通过银行汇到以上指定账号,请您尽快汇清款项,逾期订单将自动取消,汇款后请等待确认收款,到账周期一般为1-3个工作日。", remarkFont)); paragraphRemark.add(Chunk.NEWLINE); paragraphRemark.add(Chunk.NEWLINE); paragraphRemark.add(new Chunk("4.汇款金额请与应付金额保持一致,请勿多汇款或者少汇款。", remarkFont)); paragraphRemark.add(Chunk.NEWLINE); document.add(paragraphRemark); sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); pph1 = new Paragraph("打印日期:" + sdf.format(new Date()), fontChinese); pph1.setAlignment(Element.ALIGN_RIGHT); pph1.setSpacingBefore(20); document.add(pph1); response.setContentType("application/pdf; charset=utf-8"); response.setHeader("Content-Disposition", "attachment; filename=" + Encodes.urlEncode("预租确认回执") + ".pdf"); document.close(); writer.close(); OutputStream out = response.getOutputStream(); out.flush(); response.flushBuffer(); } }
水印事件TextWaterMarkPdfPageEvent.java
package com.jeeplus.modules.order.util; import java.io.IOException; 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.Phrase; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.ColumnText; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfPageEventHelper; import com.itextpdf.text.pdf.PdfWriter; /** * PDF 水印事件 * * @author xiaofei.xian 日期:2018年5月30日 上午11:25:18 */ public class TextWaterMarkPdfPageEvent extends PdfPageEventHelper { private String waterMarkText; public TextWaterMarkPdfPageEvent(String waterMarkText) { this.waterMarkText = waterMarkText; } @Override public void onEndPage(PdfWriter writer, Document document) { try { float pageWidth = document.right() + document.left();// 获取pdf内容正文页面宽度 float pageHeight = document.top() + document.bottom();// 获取pdf内容正文页面高度 // 设置水印字体格式 BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font waterMarkFont = new Font(base, 15, Font.BOLD, new BaseColor(230, 230, 230)); PdfContentByte waterMarkPdfContent = writer.getDirectContentUnder(); Phrase phrase = new Phrase(waterMarkText, waterMarkFont); ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase, pageWidth * 0.25f, pageHeight * 0.2f, 45); ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase, pageWidth * 0.25f, pageHeight * 0.5f, 45); ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase, pageWidth * 0.25f, pageHeight * 0.8f, 45); ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase, pageWidth * 0.65f, pageHeight * 0.2f, 45); ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase, pageWidth * 0.65f, pageHeight * 0.5f, 45); ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase, pageWidth * 0.65f, pageHeight * 0.8f, 45); } catch (DocumentException de) { de.printStackTrace(); } catch (IOException de) { de.printStackTrace(); } } }
页脚事件PdfFooterEvent.java
package com.jeeplus.modules.order.util; import java.io.IOException; import com.itextpdf.text.BaseColor; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Font; import com.itextpdf.text.Paragraph; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfPCell; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfPageEventHelper; import com.itextpdf.text.pdf.PdfWriter; /** * PDF 页眉事件 * * @author xiaofei.xian 日期:2018年5月30日 上午11:25:00 */ public class PdfFooterEvent extends PdfPageEventHelper { public static PdfPTable footer; public static String webUrl; public PdfFooterEvent(PdfPTable footer, String webUrl) { PdfFooterEvent.footer = footer; PdfFooterEvent.webUrl = webUrl; } @Override public void onEndPage(PdfWriter writer, Document document) { // 把页脚表格定位 footer.writeSelectedRows(0, -1, 38, 30, writer.getDirectContent()); } /** * 页脚是文字 * * @param writer * @param songti09 * @throws IOException * @throws DocumentException */ public void setTableFooter(PdfWriter writer) throws DocumentException, IOException { PdfPTable table = new PdfPTable(1); table.setTotalWidth(520f); PdfPCell cell = new PdfPCell(); cell.setBorder(1); String string = "本回执仅做财务付款申请凭证,它用无效 网址:" + webUrl; BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font FontChinese = new Font(bfChinese, 10, Font.NORMAL); FontChinese.setColor(new BaseColor(150, 150, 150)); Paragraph p = new Paragraph(string, FontChinese); cell.setPaddingLeft(10f); cell.setPaddingTop(-2f); cell.addElement(p); table.addCell(cell); PdfFooterEvent event = new PdfFooterEvent(table, webUrl); writer.setPageEvent(event); } }