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文件添加水印图片并导出,仅供参考。

如有疏漏错误之处,还请不吝赐教!

 

posted @ 2018-10-10 11:13  JalonY  阅读(9910)  评论(0编辑  收藏  举报