Java使用iText7生成PDF,學(xué)到啦!
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
前言
我們之前使用js庫html2canvas + jspdf實(shí)現(xiàn)html轉(zhuǎn)PDF、圖片,并下載(詳情請(qǐng)戳:html頁面轉(zhuǎn)PDF、圖片操作記錄),大致原理是將頁面塞到畫布里,以圖片的方式放到PDF中,生成的文件比較大,文本記錄Java使用iText7生成PDF
?
iText 7是iText強(qiáng)大的PDF工具包的最新版本,用于PDF生成,PDF編程,處理和操作,如數(shù)字簽名等
官方文檔:
? ? ? ?https://kb.itextpdf.com/home/it7kb/ebooks
?
簡(jiǎn)單生成PDF
官方文檔:
? ? ? ?https://kb.itextpdf.com/home/it7kb/ebooks/itext-7-jump-start-tutorial-for-java
根據(jù)文檔說明,我們引入依賴
????
????
????7.1.7
????
????
????
????
????????com.itextpdf
????????kernel
????????${itext7.version}
????
????
????????com.itextpdf
????????io
????????${itext7.version}
????
????
????????com.itextpdf
????????layout
????????${itext7.version}
????
????
????????com.itextpdf
????????forms
????????${itext7.version}
????
????
????????com.itextpdf
????????pdfa
????????${itext7.version}
????
?
代碼
package?cn.huanzi.qch.util;
import?com.itextpdf.html2pdf.ConverterProperties;
import?com.itextpdf.html2pdf.HtmlConverter;
import?com.itextpdf.io.font.PdfEncodings;
import?com.itextpdf.io.image.ImageDataFactory;
import?com.itextpdf.kernel.colors.Color;
import?com.itextpdf.kernel.colors.DeviceRgb;
import?com.itextpdf.kernel.events.Event;
import?com.itextpdf.kernel.events.IEventHandler;
import?com.itextpdf.kernel.events.PdfDocumentEvent;
import?com.itextpdf.kernel.font.PdfFont;
import?com.itextpdf.kernel.font.PdfFontFactory;
import?com.itextpdf.kernel.geom.PageSize;
import?com.itextpdf.kernel.geom.Rectangle;
import?com.itextpdf.kernel.pdf.PdfDocument;
import?com.itextpdf.kernel.pdf.PdfPage;
import?com.itextpdf.kernel.pdf.PdfWriter;
import?com.itextpdf.kernel.pdf.action.PdfAction;
import?com.itextpdf.kernel.pdf.annot.PdfLinkAnnotation;
import?com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import?com.itextpdf.layout.Canvas;
import?com.itextpdf.layout.Document;
import?com.itextpdf.layout.Style;
import?com.itextpdf.layout.element.*;
import?com.itextpdf.layout.font.FontProvider;
import?com.itextpdf.layout.property.TextAlignment;
import?com.itextpdf.layout.property.VerticalAlignment;
import?java.io.BufferedReader;
import?java.io.FileReader;
import?java.io.IOException;
/**
?*?itextpdf?工具類
?* iText 7是iText強(qiáng)大的PDF工具包的最新版本,用于PDF生成,PDF編程,處理和操作,如數(shù)字簽名等。
?*?https://kb.itextpdf.com/home/it7kb/ebooks
?*/
public?class?ITextPdfUtil?{
????//字體,我這里使用系統(tǒng)自帶的simhei黑體
????private?static?final?String?FONT?=?"C:/Windows/Fonts/simhei.ttf";
????//html轉(zhuǎn)pdf
????public?static?void?html2pdf(){
????????String?html?=?"";
????????//從html文件讀取內(nèi)容
????????StringBuilder?stringBuilder?=?new?StringBuilder();
????????try?(BufferedReader?reader?=?new?BufferedReader(new?FileReader("E:\\Java\\html2pdf.html"));){
????????????for?(Object?o?:??reader.lines().toArray())?{
????????????????stringBuilder.append(o);
????????????}
????????}catch?(Exception?e){
????????????e.printStackTrace();
????????}
????????html?=?stringBuilder.toString();
????????try?(PdfWriter?writer?=?new?PdfWriter("E:\\Java\\html2pdf.pdf");
?????????????PdfDocument?pdf?=?new?PdfDocument(writer);
????????){
????????????//轉(zhuǎn)換器屬性設(shè)置
????????????ConverterProperties?props?=?new?ConverterProperties();
????????????//字體
????????????props.setFontProvider(new?FontProvider());
????????????props.getFontProvider().addFont(ITextPdfUtil.FONT);
????????????//為img圖片配置基礎(chǔ)路徑
????????????props.setBaseUri("D:\\XFT?User\\Pictures\\");
????????????//HtmlConverter.convertToDocument
????????????Document?document?=?HtmlConverter.convertToDocument(html,?pdf,?props);
????????????//設(shè)置文檔屬性
????????????pdf.getDocumentInfo().setAuthor("huanzi-qch");
????????????pdf.getDocumentInfo().setTitle("IText測(cè)試html2pdf");
????????????pdf.getDocumentInfo().setSubject("XXX公司");
????????????pdf.getDocumentInfo().setMoreInfo("1","111");
????????????pdf.getDocumentInfo().setCreator("huanzi");
????????????pdf.getDocumentInfo().setKeywords("IText");
????????????//注冊(cè)事件監(jiān)聽
????????????pdf.addEventHandler(PdfDocumentEvent.END_PAGE,?new?MyEventHandler());
????????????//設(shè)置字體
????????????document.setFont(ITextPdfUtil.getPdfFont());
????????????//頁邊距
????????????document.setMargins(0,?0,?0,?0);
????????????document.close();
????????????System.out.println("操作完成!");
????????}catch?(IOException?e){
????????????e.printStackTrace();
????????????System.err.println("操作異常...");
????????}
????}
????//生成簡(jiǎn)單PDF
????public?static?void?test(){
????????//語法糖
????????try?(PdfWriter?writer?=?new?PdfWriter("E:\\Java\\test.pdf");
?????????????PdfDocument?pdf?=?new?PdfDocument(writer);
?????????????Document?document?=?new?Document(pdf,?PageSize.A4.rotate());
????????){
????????????//設(shè)置文檔屬性
????????????pdf.getDocumentInfo().setAuthor("huanzi-qch");
????????????pdf.getDocumentInfo().setTitle("IText測(cè)試PDF");
????????????pdf.getDocumentInfo().setSubject("XXX公司");
????????????pdf.getDocumentInfo().setMoreInfo("1","111");
????????????pdf.getDocumentInfo().setCreator("huanzi");
????????????pdf.getDocumentInfo().setKeywords("IText");
????????????//注冊(cè)事件監(jiān)聽
????????????pdf.addEventHandler(PdfDocumentEvent.END_PAGE,?new?MyEventHandler());
????????????//設(shè)置字體
????????????document.setFont(ITextPdfUtil.getPdfFont());
????????????//頁邊距
????????????document.setMargins(20,?20,?20,?20);
????????????//簡(jiǎn)單文字
????????????document.add(new?Paragraph("簡(jiǎn)單文字"));
????????????document.add(new?Paragraph("Hello?Word!").add(new?Tab()).add(new?Text("你好!").addStyle(new?Style().setFontSize(24))));
????????????//簡(jiǎn)單圖片
????????????document.add(new?Paragraph("簡(jiǎn)單圖片"));
????????????document.add(new?Image(ImageDataFactory.create("D:\\XFT?User\\Pictures\\logo.png")));
????????????//簡(jiǎn)單表格
????????????document.add(new?Paragraph("簡(jiǎn)單表格"));
????????????Table?table?=?new?Table(new?float[]{3,?3,?4});
????????????PdfFont?font?=?ITextPdfUtil.getPdfFont();
????????????//標(biāo)題、內(nèi)容
????????????process(table,?"姓名;年齡;電話號(hào)碼",?font,?true);
????????????for?(int?i?=?0;?i?5;?i++)?{
????????????????process(table,?"張三"+i+";"+(18+i)+";1500000000"+i,?font,?false);
????????????}
????????????document.add(table);
????????????//超鏈接
????????????document.add(new?Paragraph("超鏈接"));
????????????PdfLinkAnnotation?annotation?=?new?PdfLinkAnnotation(new?Rectangle(0,?0));
????????????annotation.setAction(PdfAction.createURI("https://itextpdf.com/"));
????????????Paragraph?p?=?new?Paragraph("更多精彩內(nèi)容,猛戳:").add(new?Link("這里",?annotation));
????????????document.add(p);
????????????//換一頁
????????????//document.add(new?AreaBreak(AreaBreakType.NEXT_PAGE));
????????????document.close();
????????????System.out.println("操作完成!");
????????}?catch?(IOException?e)?{
????????????e.printStackTrace();
????????????System.err.println("操作異常...");
????????}
????}
????//獲取統(tǒng)一字體
????public?static?PdfFont?getPdfFont(){
????????PdfFont?pdfFont?=?null;
????????try?{
????????????pdfFont?=?PdfFontFactory.createFont(ITextPdfUtil.FONT,?PdfEncodings.IDENTITY_H,true);
????????}?catch?(IOException?e)?{
????????????e.printStackTrace();
????????}
????????return?pdfFont;
????}
????//設(shè)置表格內(nèi)容
????public?static?void?process(Table?table,?String?line,?PdfFont?font,?boolean?isHeader)?{
????????String[]?split?=?line.split(";");
????????for?(String?s?:?split)?{
????????????Cell?cell?=?new?Cell().add(new?Paragraph(s).setFont(font));
????????????if?(isHeader)?{
????????????????table.addHeaderCell(cell);
????????????}?else?{
????????????????table.addCell(cell);
????????????}
????????}
????}
????/**
?????*?自定義事件監(jiān)聽
?????*
?????*?背景顏色
?????*?頁腳頁眉
?????*?文字水印
?????*
?????*?也可以分成多個(gè)EventHandler
?????*/
????protected?static?class?MyEventHandler?implements?IEventHandler?{
????????@Override
????????public?void?handleEvent(Event?event)?{
????????????PdfDocumentEvent?docEvent?=?(PdfDocumentEvent)?event;
????????????PdfDocument?pdfDoc?=?docEvent.getDocument();
????????????PdfPage?page?=?docEvent.getPage();
????????????int?pageNumber?=?pdfDoc.getPageNumber(page);
????????????Rectangle?pageSize?=?page.getPageSize();
????????????PdfCanvas?pdfCanvas?=?new?PdfCanvas(page.newContentStreamBefore(),?page.getResources(),?pdfDoc);
????????????//背景顏色
????????????Color?backgroundColor?=?new?DeviceRgb(245,?245,?245);;
????????????pdfCanvas.saveState()
????????????????????.setFillColor(backgroundColor)
????????????????????.rectangle(pageSize.getLeft(),?pageSize.getBottom(),pageSize.getWidth(),?pageSize.getHeight())
????????????????????.fill().restoreState();
????????????//頁腳頁眉
????????????PdfFont?pdfFont?=?ITextPdfUtil.getPdfFont();
????????????String?header?=?"我是頁眉";
????????????String?footer?=?"第?"+pageNumber+"?頁";
????????????pdfCanvas.beginText()
????????????????????.setFontAndSize(pdfFont,?9)
????????????????????.moveText((pageSize.getWidth()?/?2)?-?(pdfFont.getWidth(header)?/?200),?pageSize.getTop()?-?20)
????????????????????.showText(header)
????????????????????.moveText((pdfFont.getWidth(header)?/?200)?-?(pdfFont.getWidth(footer)?/?200),?-pageSize.getTop()?+?30)
????????????????????.showText(footer)
????????????????????.endText();
????????????//文字水印
????????????Canvas?canvas?=?new?Canvas(pdfCanvas,?pdfDoc,?page.getPageSize());
????????????canvas.setFontColor(new?DeviceRgb(200,?200,?200));
????????????canvas.setProperty(20,?20);
????????????canvas.setFont(pdfFont);
????????????for?(int?i?=?0;?i?5;?i++)?{
????????????????for?(int?j?=?0;?j?5;?j++)?{
????????????????????canvas.showTextAligned(new?Paragraph("我是文字水印").setOpacity(0.8f),(150?+?i?*?300),?(160?+?j?*?150),?pdfDoc.getPageNumber(page),?TextAlignment.CENTER,?VerticalAlignment.MIDDLE,?45);
????????????????}
????????????}
????????????pdfCanvas.release();
????????}
????}
????//測(cè)試
????public?static?void?main(String[]?args)?{
????????test();
????????//html2pdf();
????}
}
?
效果

?
?
生成的PDF
?
?
? 文檔屬性

?
?
?
?
HTML轉(zhuǎn)PDF
官方文檔:
https://kb.itextpdf.com/home/it7kb/ebooks/itext-7-converting-html-to-pdf-with-pdfhtml
pdfHTML是iText 7的一個(gè)附加組件,需要添加依賴
????
????
????2.1.4
????
????
????
????
????????com.itextpdf
????????html2pdf
????????${itext7.html2pdf.version}
????
代碼
代碼同上,僅main測(cè)試函數(shù)不同!
????//測(cè)試
????public?static?void?main(String[]?args)?{
????????//test();
????????html2pdf();
????}
PS:html內(nèi)容往下拉
?
效果

?
?
html頁面
????簡(jiǎn)單簡(jiǎn)歷
????"Content-Type"?content="text/html;?charset=utf-8"?/>
????"cache-control"?content="no-cache,?no-store,?must-revalidate"/>
????"pragma"?content="no-cache"/>
????"expires"?content="0"/>
????
????
"body"?class="main">
????"section">
????????"module">
????????????"list1"?style="margin:?0;">基本信息
????????????"block">
????????????????XXX/男/25歲
????????????????本科/XX學(xué)校/XX專業(yè)/2014-2018
????????????????工齡:X年
????????????????手機(jī):XXXXXXXXXX
????????????????
????????????????GitHub:"https://github.com/huanzi-qch">https://github.com/huanzi-qch
????????????????博客園:"https://www.cnblogs.com/huanzi-qch">https://www.cnblogs.com/huanzi-qch
????????????????
????????????????求職崗位:Java開發(fā)/目標(biāo)城市:南寧市/期望薪資:面議
????????????????注:已離職,一個(gè)月可到崗
????????????????
????????????????"position:?relative;top:?-350px;left:?500px;width:?100px;height:?130px;"?src="logo.png"/>
????????????
????????
????????"module">
????????????"list1">技能清單
????????????"block">
????????????????熟悉XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX。
????????????????熟悉XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX。
????????????????熟悉XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX。
????????????????熟悉XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX。
????????????????熟悉XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX。
????????????????熟悉XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX。
????????????????熟悉XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX。
????????????????熟悉XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX。
????????????????熟悉XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX。
????????????????熟悉XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX。
????????????????熟悉XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX。
????????????
????????
????????"module">
????????????"list1">工作經(jīng)歷
????????????"block">
????????????????XXX技術(shù)有限公司/Java開發(fā)工程師/2018.01?-?至今
????????????????參與多個(gè)項(xiàng)目開發(fā)、測(cè)試、部署等工作,包括:
????????????????1、XXX。
????????????????2、XXX。
????????????????3、XXX。
????????????
????????
????????"module">
????????????"list1">項(xiàng)目經(jīng)歷
????????????"block">
????????????????"list2">項(xiàng)目1
????????????????"block1">
????????????????????項(xiàng)目名稱:XXX(2020-11 —2021-11)
????????????????????項(xiàng)目介紹:XXXXXXXXXXXXXXX。
????????????????????技術(shù)架構(gòu):XXX + XXX + XXX。
????????????????????職責(zé)描述:
????????????????????1、XXXX。
????????????????????2、XXXX。
????????????????????3、XXXX。
????????????????????4、XXXX。
????????????????
????????????????"list2">項(xiàng)目2
????????????????"block1">
????????????????????項(xiàng)目名稱:XXX(2020-11 —2021-11)
????????????????????項(xiàng)目介紹:XXXXXXXXXXXXXXX。
????????????????????技術(shù)架構(gòu):SpringBoot + Vue + Element-UI + ECharts。
????????????????????職責(zé)描述:
????????????????????1、XXXX。
????????????????????2、XXXX。
????????????????????3、XXXX。
????????????????????4、XXXX。
????????????????
????????????
????????
????????"module">
????????????"list1">自我評(píng)價(jià)
????????????"block">
????????????????1、XXXX;
????????????????2、XXXX;
????????????????3、XXXX;
????????????
????????
????

?
?
生成的PDF

?
?
后記
不管是前端生成PDF,還是后端生成PDF,能實(shí)現(xiàn)需求就是好技術(shù)!?
? 作者?|??huanzi-qch
來源 |??cnblogs.com/huanzi-qch/p/15540276.html

加鋒哥微信:?java3459?? 圍觀鋒哥朋友圈,每天推送Java干貨!
