一、前言
首先需要在Maven中添加相应的jar包依赖,若项目没用到Maven,也可自行下载相应所需的jar包(itextpdf.jar 与 itext-asian.jar),如下图所示。
Maven中添加依赖jar包如下所示:
1 23 7com.itextpdf 4itextpdf 55.3.2 68 12com.itextpdf 9itext-asian 105.2.0 11
二、正文
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 ListcorpIfs = 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 //表格内容样式4106 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.4165 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 Transparency177 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 轴和之前的保持一致,底边界-20108 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文件添加水印图片并导出,仅供参考。
如有疏漏错误之处,还请不吝赐教!