JavaWeb项目生成PDF文件添加水印图片并导出
一、前言
首先需要在Maven中添加相应的jar包依赖,若项目没用到Maven,也可自行下载相应所需的jar包(itextpdf.jar 与 itext-asian.jar),如下图所示。点此下载
Maven中添加依赖jar包如下所示:
1 <!-- pdf start --> 2 <dependency> 3 <groupId>com.itextpdf</groupId> 4 <artifactId>itextpdf</artifactId> 5 <version>5.3.2</version> 6 </dependency> 7 <dependency> 8 <groupId>com.itextpdf</groupId> 9 <artifactId>itext-asian</artifactId> 10 <version>5.2.0</version> 11 </dependency> 12 <!-- pdf end -->
二、正文
1、首先获取需要填写至PDF中的数据,如下述所示,realPath为添加图片的路径,test.pdf为未添加图片的PDF临时文件,在Tomcat服务器对应路径下,以及导出的PDF文件存至桌面:
1 //点击下载获取企业信息并存至Pdf 2 @RequestMapping(value="/downloadPdf.do") 3 @ResponseBody 4 public String downloadPdf(@RequestParam(value = "download_corp_id") String download_corp_id, HttpServletRequest request) throws Exception { 5 List<TCorp> corpIfs = searchCorpService.getCorpInfo(Integer.parseInt(download_corp_id)); 6 TCorp tCorp = new TCorp(); 7 for (TCorp corpInfo: corpIfs){ 8 tCorp.setId(corpInfo.getId()); 9 tCorp.setRegNo(corpInfo.getRegNo()); 10 tCorp.setCorpName(corpInfo.getCorpName()); 11 tCorp.setCorpAddr(corpInfo.getCorpAddr()); 12 tCorp.setBelongOrg(corpInfo.getBelongOrg()); 13 tCorp.setBelongDistOrg(corpInfo.getBelongDistOrg()); 14 tCorp.setBelongTrade(corpInfo.getBelongTrade()); 15 tCorp.setEconKind(corpInfo.getEconKind()); 16 tCorp.setAdmitMain(corpInfo.getAdmitMain()); 17 tCorp.setStartDate(corpInfo.getStartDate()); 18 tCorp.setCheckDate(corpInfo.getCheckDate()); 19 tCorp.setOperManIdentNo(corpInfo.getOperManIdentNo()); 20 tCorp.setOperManName(corpInfo.getOperManName()); 21 tCorp.setCorpStatus(corpInfo.getCorpStatus()); 22 tCorp.setRegCapi(corpInfo.getRegCapi()); 23 tCorp.setPaidCapi(corpInfo.getPaidCapi()); 24 tCorp.setFareTermStart(corpInfo.getFareTermStart()); 25 tCorp.setFareTermEnd(corpInfo.getFareTermEnd()); 26 tCorp.setFareScope(corpInfo.getFareScope()); 27 tCorp.setUniScid(corpInfo.getUniScid()); 28 tCorp.setCorpTel(corpInfo.getCorpTel()); 29 tCorp.setCorpWebUrl(corpInfo.getCorpWebUrl()); 30 tCorp.setCorpLogo(corpInfo.getCorpLogo()); 31 tCorp.setCorpEmail(corpInfo.getCorpEmail()); 32 tCorp.setPracPersonNum(corpInfo.getPracPersonNum()); 33 tCorp.setOrgInstCode(corpInfo.getOrgInstCode()); 34 tCorp.setTaxpayNum(corpInfo.getTaxpayNum()); 35 tCorp.setStaffSize(corpInfo.getStaffSize()); 36 tCorp.setEnglishName(corpInfo.getEnglishName()); 37 tCorp.setFormerName(corpInfo.getFormerName()); 38 tCorp.setCorpInfo(corpInfo.getCorpInfo()); 39 tCorp.setCreateDate(corpInfo.getCreateDate()); 40 tCorp.setCreateOrg(corpInfo.getCreateOrg()); 41 } 42 43 String realPath = request.getSession().getServletContext().getRealPath("/") + "\\icon\\logo_64.png"; 44 PDFReport.settCorp(tCorp); 45 new PDFReport("test.pdf").generatePDF(); 46 PDFUtil.addImage("test.pdf", "C:\\Users\\Administrator\\Desktop\\"+tCorp.getCorpName()+".pdf",realPath); 47 48 return "提示:数据导出成功!"; 49 }
2、PDFReport类中申明一个文档类型建立Document对象,设置页面样式等:
1 package util; 2 3 import com.itextpdf.text.Document; 4 import com.itextpdf.text.PageSize; 5 import com.itextpdf.text.Rectangle; 6 import com.itextpdf.text.pdf.PdfPTable; 7 import com.itextpdf.text.pdf.PdfWriter; 8 import entity.TCorp; 9 10 import java.io.File; 11 import java.io.FileOutputStream; 12 13 public class PDFReport { 14 private static TCorp tCorp; 15 16 Document document = new Document();// 建立一个Document对象 17 18 public PDFReport(String out) { 19 try { 20 File file = new File(out); 21 file.createNewFile(); 22 Rectangle pageSize = new Rectangle(PageSize.A4); 23 document.setPageSize(pageSize); 24 PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file)); 25 PDFBuilder builder = new PDFBuilder(); 26 writer.setPageEvent(builder); 27 document.open(); 28 PdfPTable table = generatePDF(); 29 document.add(table); 30 document.close(); 31 } catch (Exception e) { 32 e.printStackTrace(); 33 } 34 } 35 36 public static void settCorp(TCorp tCorp) { 37 PDFReport.tCorp = tCorp; 38 } 39 40 41 public PdfPTable generatePDF() { 42 //设置单元格为5列 43 PdfPTable table = PDFUtil.createTable(5); 44 45 table.addCell(PDFUtil.createHeadCell("企业信息列表")); 46 table.addCell(PDFUtil.createTitleCell_1("企业名称")); 47 table.addCell(PDFUtil.createCell_1(tCorp.getCorpName())); 48 table.addCell(PDFUtil.createTitleCell_1("联系方式")); 49 table.addCell(PDFUtil.createCell_1(tCorp.getCorpTel())); 50 table.addCell(PDFUtil.createCell_2("Logo")); 51 52 table.addCell(PDFUtil.createTitleCell_1("企业邮箱")); 53 table.addCell(PDFUtil.createCell_1(tCorp.getCorpEmail())); 54 table.addCell(PDFUtil.createTitleCell_1("网址")); 55 table.addCell(PDFUtil.createCell_1(tCorp.getCorpWebUrl())); 56 57 table.addCell(PDFUtil.createTitleCell_1("企业地址")); 58 table.addCell(PDFUtil.createCell_1(tCorp.getCorpAddr())); 59 table.addCell(PDFUtil.createTitleCell_1("注册/实缴")); 60 table.addCell(PDFUtil.createCell_1(String.valueOf(tCorp.getRegCapi())+"万 / "+String.valueOf(tCorp.getPaidCapi())+"万")); 61 62 table.addCell(PDFUtil.createTitleCell_1("成立日期")); 63 table.addCell(PDFUtil.createCell_1(tCorp.getStartDate())); 64 table.addCell(PDFUtil.createTitleCell_1("统一社会信用代码")); 65 table.addCell(PDFUtil.createCell_3(tCorp.getUniScid())); 66 67 table.addCell(PDFUtil.createTitleCell_1("法定代表人")); 68 table.addCell(PDFUtil.createCell_1(tCorp.getOperManName())); 69 table.addCell(PDFUtil.createTitleCell_1("纳税人识别号")); 70 table.addCell(PDFUtil.createCell_3(tCorp.getTaxpayNum())); 71 72 table.addCell(PDFUtil.createTitleCell_1("注册号")); 73 table.addCell(PDFUtil.createCell_1(tCorp.getRegNo())); 74 table.addCell(PDFUtil.createTitleCell_1("组织机构代码")); 75 table.addCell(PDFUtil.createCell_3(tCorp.getOrgInstCode())); 76 77 table.addCell(PDFUtil.createTitleCell_1("公司类型")); 78 table.addCell(PDFUtil.createCell_1(tCorp.getEconKind())); 79 table.addCell(PDFUtil.createTitleCell_1("人员规模")); 80 table.addCell(PDFUtil.createCell_3(tCorp.getStaffSize())); 81 82 table.addCell(PDFUtil.createTitleCell_1("营业期限")); 83 table.addCell(PDFUtil.createCell_1(tCorp.getFareTermStart()+" 至 "+tCorp.getFareTermEnd())); 84 table.addCell(PDFUtil.createTitleCell_1("登记机关")); 85 table.addCell(PDFUtil.createCell_3(tCorp.getBelongOrg())); 86 87 table.addCell(PDFUtil.createTitleCell_1("核准日期")); 88 table.addCell(PDFUtil.createCell_1(tCorp.getCheckDate())); 89 table.addCell(PDFUtil.createTitleCell_1("所属行业")); 90 table.addCell(PDFUtil.createCell_3(tCorp.getBelongTrade())); 91 92 table.addCell(PDFUtil.createTitleCell_1("英文名称")); 93 table.addCell(PDFUtil.createCell_1(tCorp.getEnglishName())); 94 table.addCell(PDFUtil.createTitleCell_1("曾用名")); 95 table.addCell(PDFUtil.createCell_3(tCorp.getFormerName())); 96 97 table.addCell(PDFUtil.createTitleCell_2("经营范围")); 98 table.addCell(PDFUtil.createCell_4(tCorp.getFareScope())); 99 100 return table; 101 } 102 }
3、PDFUtil类中设置字体、表格样式、以及水印文字样式,setColspan函数为设置所跨列数,setRowspan函数为设置所跨行数:
1 package util; 2 3 import com.itextpdf.text.*; 4 import com.itextpdf.text.pdf.*; 5 6 import javax.imageio.ImageIO; 7 import java.io.BufferedOutputStream; 8 import java.io.File; 9 import java.io.FileOutputStream; 10 11 public class PDFUtil { 12 private static Font headfont ; // 设置字体大小 13 private static Font keyfont; // 设置字体大小 14 private static Font textfont; // 设置字体大小 15 16 static{ 17 BaseFont bfChinese; 18 try { 19 bfChinese = BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED); 20 headfont = new Font(bfChinese, 24, Font.BOLD,BaseColor.BLACK);// 设置字体大小 21 keyfont = new Font(bfChinese, 12, Font.BOLD,BaseColor.BLACK);// 设置字体大小 22 textfont = new Font(bfChinese, 10, Font.NORMAL,BaseColor.BLACK);// 设置字体大小 23 } catch (Exception e) { 24 e.printStackTrace(); 25 } 26 } 27 28 //表格标题 29 public static PdfPCell createHeadCell(String value){ 30 PdfPCell cell = new PdfPCell(); 31 cell.setVerticalAlignment(15); 32 cell.setHorizontalAlignment(15); 33 cell.setColspan(5); 34 cell.setPhrase(new Phrase(value,headfont)); 35 cell.setHorizontalAlignment(Element.ALIGN_CENTER); //水平居中 36 cell.setPadding(10.0f); 37 cell.setBorder(0); 38 cell.setPaddingTop(5.0f); 39 cell.setPaddingBottom(18.0f); 40 return cell; 41 } 42 43 //表格表头样式1 44 public static PdfPCell createTitleCell_1(String value){ 45 PdfPCell cell = new PdfPCell(); 46 cell.setVerticalAlignment(Element.ALIGN_MIDDLE); 47 cell.setHorizontalAlignment(Element.ALIGN_CENTER); 48 cell.setPhrase(new Phrase(value, keyfont)); 49 cell.setBackgroundColor(new BaseColor(29, 181, 238)); 50 cell.setColspan(1); 51 cell.setFixedHeight(35); 52 return cell; 53 } 54 55 //表格表头样式2 56 public static PdfPCell createTitleCell_2(String value){ 57 PdfPCell cell = new PdfPCell(); 58 cell.setVerticalAlignment(Element.ALIGN_MIDDLE); 59 cell.setHorizontalAlignment(Element.ALIGN_CENTER); 60 cell.setPhrase(new Phrase(value, keyfont)); 61 cell.setBackgroundColor(new BaseColor(29, 181, 238)); 62 cell.setColspan(1); 63 cell.setRowspan(3); 64 cell.setFixedHeight(105); 65 return cell; 66 } 67 68 //表格内容样式1 69 public static PdfPCell createCell_1(String value){ 70 PdfPCell cell = new PdfPCell(); 71 cell.setVerticalAlignment(Element.ALIGN_MIDDLE); 72 cell.setHorizontalAlignment(Element.ALIGN_CENTER); 73 cell.setPhrase(new Phrase(value,textfont)); 74 cell.setBackgroundColor(new BaseColor(255, 255, 255)); 75 cell.setColspan(1); 76 cell.setFixedHeight(35); 77 return cell; 78 } 79 80 //表格内容样式2 81 public static PdfPCell createCell_2(String value){ 82 PdfPCell cell = new PdfPCell(); 83 cell.setVerticalAlignment(Element.ALIGN_MIDDLE); 84 cell.setHorizontalAlignment(Element.ALIGN_CENTER); 85 cell.setPhrase(new Phrase(value,textfont)); 86 cell.setBackgroundColor(new BaseColor(255, 255, 255)); 87 cell.setColspan(1); 88 cell.setRowspan(3); 89 cell.setFixedHeight(105); 90 return cell; 91 } 92 93 //表格内容样式3 94 public static PdfPCell createCell_3(String value){ 95 PdfPCell cell = new PdfPCell(); 96 cell.setVerticalAlignment(Element.ALIGN_MIDDLE); 97 cell.setHorizontalAlignment(Element.ALIGN_CENTER); 98 cell.setPhrase(new Phrase(value,textfont)); 99 cell.setBackgroundColor(new BaseColor(255, 255, 255)); 100 cell.setColspan(2); 101 cell.setFixedHeight(35); 102 return cell; 103 } 104 105 //表格内容样式4 106 public static PdfPCell createCell_4(String value){ 107 PdfPCell cell = new PdfPCell(); 108 cell.setVerticalAlignment(Element.ALIGN_MIDDLE); 109 cell.setHorizontalAlignment(Element.ALIGN_CENTER); 110 cell.setPhrase(new Phrase(value,textfont)); 111 cell.setBackgroundColor(new BaseColor(255, 255, 255)); 112 cell.setColspan(4); 113 cell.setRowspan(3); 114 cell.setFixedHeight(105); 115 return cell; 116 } 117 118 //生成表格 119 public static PdfPTable createTable(int colNumber){ 120 int widths[] = { 35,40,35,35,30 }; 121 PdfPTable baseTable = new PdfPTable(colNumber); 122 baseTable.setWidthPercentage(100); 123 baseTable.setSpacingBefore(10); 124 try { 125 baseTable.setWidths(widths); 126 } catch (DocumentException e) { 127 e.printStackTrace(); 128 } 129 return baseTable; 130 } 131 132 133 public static void addImage(String input,String output,String realPath) throws Exception{ 134 BufferedOutputStream out = new BufferedOutputStream( 135 new FileOutputStream(new File(output))); 136 PdfReader reader = new PdfReader(input); 137 PdfStamper stamper = new PdfStamper(reader, out); 138 addWatermark(stamper,"测试添加水印文字"); 139 int total = reader.getNumberOfPages(); 140 try { 141 Image image = Image.getInstance(realPath); 142 image.setAbsolutePosition(350, 200); 143 image.scaleToFit(160, 70); 144 PdfContentByte content= stamper.getOverContent(total);// 在内容上方加水印 145 content.addImage(image); 146 }catch (Exception e){ 147 e.printStackTrace(); 148 } 149 150 stamper.close(); 151 reader.close(); 152 } 153 154 public static void addWatermark(PdfStamper pdfStamper, String waterMarkName) throws Exception { 155 PdfContentByte content; 156 BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", 157 BaseFont.NOT_EMBEDDED); 158 Rectangle pageRect; 159 PdfGState gs = new PdfGState(); 160 try { 161 if (base == null || pdfStamper == null) { 162 return; 163 } 164 // 设置透明度为0.4 165 gs.setFillOpacity(0.3f); 166 gs.setStrokeOpacity(0.3f); 167 int toPage = pdfStamper.getReader().getNumberOfPages(); 168 for (int i = 1; i <= toPage; i++) { 169 pageRect = pdfStamper.getReader().getPageSizeWithRotation(i); 170 // 计算水印X,Y坐标 171 float x = pageRect.getWidth() / 2; 172 float y = pageRect.getHeight() / 2; 173 // 获得PDF最顶层 174 content = pdfStamper.getOverContent(i); 175 content.saveState(); 176 // set Transparency 177 content.setGState(gs); 178 content.beginText(); 179 content.setColorFill(BaseColor.GRAY); 180 content.setFontAndSize(base, 30); 181 // 水印文字成45度角倾斜 182 content.showTextAligned(Element.ALIGN_CENTER, waterMarkName, x, 183 y, 45); 184 content.endText(); 185 } 186 } catch (Exception ex) { 187 ex.printStackTrace(); 188 } 189 } 190 }
4、PDFBuilder类中为设置页面附加属性:
1 package util; 2 3 import com.itextpdf.text.*; 4 import com.itextpdf.text.pdf.*; 5 6 import java.io.IOException; 7 8 public class PDFBuilder extends PdfPageEventHelper { 9 /** 10 * 页眉 11 */ 12 public String header = ""; 13 14 /** 15 * 文档字体大小,页脚页眉最好和文本大小一致 16 */ 17 public int presentFontSize = 12; 18 19 20 // 模板 21 public PdfTemplate total; 22 23 // 基础字体对象 24 public BaseFont bf = null; 25 26 // 利用基础字体生成的字体对象,一般用于生成中文文字 27 public Font fontDetail = null; 28 29 /** 30 * 31 * Creates a new instance of PdfReportM1HeaderFooter 无参构造方法. 32 * 33 */ 34 public PDFBuilder() { 35 36 } 37 38 public void setHeader(String header) { 39 this.header = header; 40 } 41 42 /** 43 * 44 * TODO 文档打开时创建模板 45 * 46 * @see com.itextpdf.text.pdf.PdfPageEventHelper#onOpenDocument(com.itextpdf.text.pdf.PdfWriter, 47 * com.itextpdf.text.Document) 48 */ 49 public void onOpenDocument(PdfWriter writer, Document document) { 50 total = writer.getDirectContent().createTemplate(50, 50);// 共 页 的矩形的长宽高 51 } 52 53 /** 54 * 55 * TODO 关闭每页的时候,写入页眉,写入'第几页共'这几个字。 56 * 57 * @see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(com.itextpdf.text.pdf.PdfWriter, 58 * com.itextpdf.text.Document) 59 */ 60 public void onEndPage(PdfWriter writer, Document document) { 61 this.addPage(writer, document); 62 } 63 64 //加分页 65 public void addPage(PdfWriter writer, Document document){ 66 try { 67 if (bf == null) { 68 bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false); 69 } 70 if (fontDetail == null) { 71 fontDetail = new Font(bf, presentFontSize, Font.NORMAL);// 数据体字体 72 } 73 } catch (DocumentException e) { 74 e.printStackTrace(); 75 } catch (IOException e) { 76 e.printStackTrace(); 77 } 78 79 // 1.写入页眉 80 ColumnText.showTextAligned(writer.getDirectContent(), 81 Element.ALIGN_LEFT, new Phrase(header, fontDetail), 82 document.left(), document.top() + 20, 0); 83 // 2.写入前半部分的 第 X页/共 84 int pageS = writer.getPageNumber(); 85 String foot1 = "第 " + pageS + " 页 / 共"; 86 Phrase footer = new Phrase(foot1, fontDetail); 87 88 // 3.计算前半部分的foot1的长度,后面好定位最后一部分的'Y页'这俩字的x轴坐标,字体长度也要计算进去 = len 89 float len = bf.getWidthPoint(foot1, presentFontSize); 90 91 // 4.拿到当前的PdfContentByte 92 PdfContentByte cb = writer.getDirectContent(); 93 94 // 5.写入页脚1,x轴就是(右margin+左margin + right() -left()- len)/2.0F 95 // 再给偏移20F适合人类视觉感受,否则肉眼看上去就太偏左了 96 // ,y轴就是底边界-20,否则就贴边重叠到数据体里了就不是页脚了;注意Y轴是从下往上累加的,最上方的Top值是大于Bottom好几百开外的。 97 ColumnText 98 .showTextAligned( 99 cb, 100 Element.ALIGN_CENTER, 101 footer, 102 (document.rightMargin() + document.right() 103 + document.leftMargin() - document.left() - len) / 2.0F + 20F, 104 document.bottom() - 20, 0); 105 106 // 6.写入页脚2的模板(就是页脚的Y页这俩字)添加到文档中,计算模板的和Y轴,X=(右边界-左边界 - 前半部分的len值)/2.0F + 107 // len , y 轴和之前的保持一致,底边界-20 108 cb.addTemplate(total, (document.rightMargin() + document.right() 109 + document.leftMargin() - document.left()) / 2.0F + 20F, 110 document.bottom() - 20); // 调节模版显示的位置 111 112 } 113 114 115 /** 116 * 117 * TODO 关闭文档时,替换模板,完成整个页眉页脚组件 118 * 119 * @see com.itextpdf.text.pdf.PdfPageEventHelper#onCloseDocument(com.itextpdf.text.pdf.PdfWriter, 120 * com.itextpdf.text.Document) 121 */ 122 public void onCloseDocument(PdfWriter writer, Document document) { 123 // 7.最后一步,是关闭文档的时候,将模板替换成实际的 Y 值,至此,page x of y 制作完毕,完美兼容各种文档size。 124 total.beginText(); 125 total.setFontAndSize(bf, presentFontSize);// 生成的模版的字体、颜色 126 String foot2 = " " + (writer.getPageNumber()-1) + " 页"; 127 total.showText(foot2);// 模版显示的内容 128 total.endText(); 129 total.closePath(); 130 } 131 }
最后附上生成的PDF效果图:
本文学习参考了:https://blog.csdn.net/qq_30490591/article/details/53434777
至此是关于JavaWeb项目生成PDF文件添加水印图片并导出,仅供参考。
如有疏漏错误之处,还请不吝赐教!