OpenPdf组件替换Itext方案
OpenPdf組件替換Itext方案
- OpenPdf簡(jiǎn)介
- 上代碼
- 1、pdf構(gòu)建接口創(chuàng)建
- 2、實(shí)踐
- gitee項(xiàng)目地址
- 關(guān)于源碼本人還在研究中,后續(xù)會(huì)根據(jù)實(shí)際用到的進(jìn)行相關(guān)代碼解析和案例講解
OpenPdf簡(jiǎn)介
OpenPDF是一個(gè)Java庫,用于創(chuàng)建和編輯具有LGPL和MPL開源許可證的PDF文件。
官方git地址 鏈接: https://github.com/LibrePDF/OpenPDF
OpenPDF是iText的LGPL/MPL開源后續(xù)版本,它基于iText 4svn標(biāo)記的fork、fork。我們歡迎其他開發(fā)者的貢獻(xiàn)。請(qǐng)隨時(shí)向這個(gè)GitHub存儲(chǔ)庫提交pull-requests和錯(cuò)誤報(bào)告。
由于Itext 5.0和7.0要求使用它的項(xiàng)目也得開源,但這基本上不符合企業(yè)的項(xiàng)目。
上代碼
若項(xiàng)目已有itext的相關(guān)構(gòu)建代碼,基本上就是重新引入包即可,相關(guān)接口的名字基本上一樣。
這里引用一個(gè)demo創(chuàng)建相關(guān)接口。
項(xiàng)目結(jié)構(gòu)為SpringBoot +thymeleaf+maven項(xiàng)目,如圖所示:
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.0</version><relativePath/></parent><groupId>com.demo</groupId><artifactId>openPdfDemo</artifactId><version>0.0.1-SNAPSHOT</version><name>openPdfDemo</name><description>openPdfDemo</description><properties><java.version>8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>com.github.librepdf</groupId><artifactId>openpdf</artifactId><version>1.3.29</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>1、pdf構(gòu)建接口創(chuàng)建
創(chuàng)建PdfCreator接口類,對(duì)操作步驟進(jìn)行抽象化,方便后續(xù)擴(kuò)展。
import com.lowagie.text.DocumentException;import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Map;/*** pdf生成器接口*/ public interface PdfCreator {/*** 初始化** @return PdfCreator* @throws DocumentException 文檔操作異常* @throws IOException IO操作異常*/PdfCreator init() throws DocumentException, IOException;/*** 構(gòu)建pdf** @param map 導(dǎo)出數(shù)據(jù)參數(shù)* @return ByteArrayOutputStream* @throws DocumentException 文檔操作異常* @throws IOException IO操作異常*/ByteArrayOutputStream creator(Map<String, Object> map) throws DocumentException, IOException;/*** 資源關(guān)閉** @throws DocumentException 文檔操作異常* @throws IOException IO操作異常*/void close() throws DocumentException, IOException; }創(chuàng)建 PdfCreateStrategy接口:
import com.lowagie.text.DocumentException;import java.io.IOException; import java.util.Map;/*** pdf 構(gòu)建策略-用于不同pdf時(shí)指向各自的pdf構(gòu)建實(shí)現(xiàn)*/ public interface PdfCreateStrategy {/*** 夠構(gòu)建方法** @param map 導(dǎo)出數(shù)據(jù)所需參數(shù)* @throws DocumentException 文檔操作異常* @throws IOException IO操作異常*/void execute(Map<String, Object> map) throws DocumentException, IOException; }創(chuàng)建抽象實(shí)現(xiàn)類AbstractPdfCreator,將共用部分進(jìn)行提取
import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Font; import com.lowagie.text.Header; import com.lowagie.text.PageSize; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.PdfPageEventHelper; import com.lowagie.text.pdf.PdfWriter;import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Map;/*** pdf構(gòu)建抽象生成類*/ public abstract class AbstractPdfCreator implements PdfCreator, PdfCreateStrategy {/*** 頁框大小,采用的類型有 "crop", "trim", "art" and "bleed".,這里采用 "art"*/private static final String BOX_NAME = "art";/*** 文檔類*/protected Document document;/*** 基礎(chǔ)字體*/protected BaseFont baseFont;/*** 字體樣式*/protected Font font;/*** 字體大小*/protected int fontSize;/*** 頁面框架大小配置*/protected Rectangle pageSize;/*** 字節(jié)輸出流*/private ByteArrayOutputStream byteArrayOutputStream;/*** pdf構(gòu)建操作轉(zhuǎn)為字節(jié)流** @param map 導(dǎo)出數(shù)據(jù)參數(shù)* @return ByteArrayOutputStream* @throws DocumentException 文檔操作異常* @throws IOException IO操作異常*/@Overridepublic ByteArrayOutputStream creator(Map<String, Object> map) throws DocumentException, IOException {execute(map);close();return byteArrayOutputStream;}/*** pdf構(gòu)建執(zhí)行** @param map 導(dǎo)出數(shù)據(jù)所需參數(shù)* @throws DocumentException 文檔操作異常* @throws IOException IO操作異常*/@Overridepublic abstract void execute(Map<String, Object> map) throws DocumentException, IOException;/*** 默認(rèn)初始化** @return PdfCreator* @throws DocumentException 文檔操作異常* @throws IOException IO操作異常*/@Overridepublic PdfCreator init() throws DocumentException, IOException {return init(baseFont, fontSize, font, pageSize, null);}/*** 自定義初始化監(jiān)聽** @param helper 自定義文檔操作監(jiān)聽* @return PdfCreator* @throws DocumentException 文檔操作異常* @throws IOException IO操作異常*/public PdfCreator init(PdfPageEventHelper helper) throws DocumentException, IOException {return init(baseFont, fontSize, font, pageSize, helper);}/*** 自定義初始化參數(shù)** @param baseFont 基礎(chǔ)字體* @param fontSize 字體大小* @param font 字體樣式* @param rectangle 頁面大小設(shè)置* @param pdfPageEventHelper 文檔操作監(jiān)聽* @return PdfCreator* @throws DocumentException 文檔操作異常* @throws IOException IO操作異常*/public PdfCreator init(BaseFont baseFont, int fontSize, Font font, Rectangle rectangle, PdfPageEventHelper pdfPageEventHelper) throws DocumentException, IOException {this.baseFont = null != baseFont ? baseFont : BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", Boolean.FALSE);this.fontSize = 0 != fontSize ? fontSize : Header.PARAGRAPH;this.font = null != font ? font : new Font(this.baseFont, this.fontSize, Font.NORMAL);this.pageSize = null != pageSize ? pageSize : PageSize.A4;document = new Document();document.setMargins(30, 30, 50, 90);byteArrayOutputStream = new ByteArrayOutputStream();PdfWriter writer = PdfWriter.getInstance(document, byteArrayOutputStream);writer.setBoxSize(BOX_NAME, this.pageSize);if (null != pdfPageEventHelper) {writer.setPageEvent(pdfPageEventHelper);}document.open();return this;}/*** 資源關(guān)閉** @throws DocumentException* @throws IOException IO操作異常*/@Overridepublic void close() throws IOException {document.close();byteArrayOutputStream.close();} }自定義監(jiān)聽器PdfPageEventListener創(chuàng)建
import com.lowagie.text.Document; import com.lowagie.text.Element; import com.lowagie.text.Font; import com.lowagie.text.Phrase; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.CMYKColor; import com.lowagie.text.pdf.ColumnText; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfPageEventHelper; import com.lowagie.text.pdf.PdfTemplate; import com.lowagie.text.pdf.PdfWriter; import org.springframework.util.StringUtils;import java.io.IOException;/*** pdf頁面自定義監(jiān)聽器*/ public class PdfPageEventListener extends PdfPageEventHelper {/*** pdf標(biāo)題字體大小*/private int headerFontSize;/*** pdf標(biāo)題寬度*/private Float headerWidth;/*** pdf標(biāo)題高度*/private Float headerHeight;/*** pdf標(biāo)題模板*/private PdfTemplate headerTemplate;/*** pdf標(biāo)題基礎(chǔ)字體*/private BaseFont headerBaseFont;/*** pdf標(biāo)題字體樣式*/private Font headerFont;/*** pdf編號(hào)(一般左上角都會(huì)有類似流水號(hào)的編號(hào),可有可無)*/private String noticeCode;/*** pdf簽字(可有可無,根據(jù)實(shí)際情況進(jìn)行賦值)*/private String signature;/*** 構(gòu)建器,進(jìn)行基本信息初始化** @param headerFontSize pdf標(biāo)題字體大小* @param headerWidth pdf標(biāo)題寬度* @param headerHeight pdf標(biāo)題高度* @param headerBaseFont pdf標(biāo)題基礎(chǔ)字體* @param headerFont pdf標(biāo)題字體樣式* @param noticeCode pdf編號(hào)* @param signature pdf簽字*/public PdfPageEventListener(int headerFontSize, Float headerWidth, Float headerHeight, BaseFont headerBaseFont, Font headerFont, String noticeCode, String signature) {this.headerFontSize = headerFontSize;this.headerWidth = headerWidth;this.headerHeight = headerHeight;this.headerBaseFont = headerBaseFont;this.headerFont = headerFont;this.noticeCode = noticeCode;this.signature = signature;}/*** pdf監(jiān)視器構(gòu)建** @return Builder*/public static Builder build() {return new Builder();}/*** 重寫文檔初始化的模板*/@Overridepublic void onOpenDocument(PdfWriter writer, Document document) {headerTemplate = writer.getDirectContent().createTemplate(headerWidth, headerHeight);}/*** 重寫每一頁結(jié)束事件,等所有內(nèi)容加載完畢后,進(jìn)行頁眉的數(shù)據(jù)加載和賦值*/@Overridepublic void onEndPage(PdfWriter writer, Document document) {try {if (headerBaseFont == null) {headerBaseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", Boolean.FALSE);}if (headerFont == null) {headerFont = new Font(headerBaseFont, headerFontSize, Font.NORMAL);}} catch (IOException e) {e.printStackTrace();}//獲取文檔內(nèi)容PdfContentByte pdfContentByte = writer.getDirectContent();float left = document.left();float right = document.right();float top = document.top();float bottom = document.bottom();int pageNumber = writer.getPageNumber();String noticeCodeText = StringUtils.isEmpty(noticeCode) ? "" : "編號(hào):" + noticeCode;String previousHeaderText = "第 " + pageNumber + " 頁 /共";Phrase headerPhrase = new Phrase(previousHeaderText, headerFont);Phrase noticePhrase = new Phrase(noticeCodeText, headerFont);Phrase signaturePhrase = new Phrase(signature, headerFont);float noticeLen = headerBaseFont.getWidthPoint(noticeCodeText, headerFontSize);float headerLen = headerBaseFont.getWidthPoint(previousHeaderText, headerFontSize);float signatureLen = headerBaseFont.getWidthPoint(signature, headerFontSize);float x0 = left + noticeLen / 2;float x1 = right - headerLen / 2 - 20F;float x2 = right - 20F;float x3 = right - signatureLen / 2;float y1 = top + 10F;float y2 = bottom - 40F;ColumnText.showTextAligned(pdfContentByte, Element.ALIGN_CENTER, noticePhrase, x0, y1, Element.HEADER);ColumnText.showTextAligned(pdfContentByte, Element.ALIGN_CENTER, headerPhrase, x1, y1, Element.HEADER);ColumnText.showTextAligned(pdfContentByte, Element.ALIGN_CENTER, signaturePhrase, x3, y2, Element.HEADER);pdfContentByte.addTemplate(headerTemplate, x2, y1);float lineY = top + 6f;CMYKColor magentaColor = new CMYKColor(1.f, 1.f, 1.f, 1.f);pdfContentByte.setColorStroke(magentaColor);pdfContentByte.moveTo(left, lineY);pdfContentByte.lineTo(left, lineY);pdfContentByte.closePathStroke();}/*** 文檔結(jié)束后,將總頁碼放在文檔上*/@Overridepublic void onCloseDocument(PdfWriter writer, Document document) {headerTemplate.beginText();headerTemplate.setFontAndSize(headerBaseFont, headerFontSize);int pageNumber = writer.getPageNumber() - 1;String behindHeaderText = " " + pageNumber + " 頁";headerTemplate.showText(behindHeaderText);headerTemplate.endText();headerTemplate.closePath();}/*** 自定義一個(gè)構(gòu)建器,設(shè)置頁面相關(guān)信息*/public static class Builder {private int headerFontSize;private Float headerWidth;private Float headerHeight;private PdfTemplate headerTemplate;private BaseFont headerBaseFont;private Font headerFont;private String noticeCode;private String signature;Builder() {headerFontSize = Font.DEFAULTSIZE;headerWidth = 50F;headerHeight = 50F;try {headerBaseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", Boolean.FALSE);} catch (IOException e) {e.printStackTrace();}headerFont = new Font(headerBaseFont, headerFontSize, Font.NORMAL);noticeCode = "";signature = "";}public Builder setHeaderFontSize(int headerFontSize) {this.headerFontSize = headerFontSize;return this;}public Builder setHeaderWidth(Float headerWidth) {this.headerWidth = headerWidth;return this;}public Builder setHeaderHeight(Float headerHeight) {this.headerHeight = headerHeight;return this;}public Builder setHeaderTemplate(PdfTemplate headerTemplate) {this.headerTemplate = headerTemplate;return this;}public Builder setHeaderBaseFont(BaseFont headerBaseFont) {this.headerBaseFont = headerBaseFont;return this;}public Builder setHeaderFont(Font headerFont) {this.headerFont = headerFont;return this;}public Builder setNoticeCode(String noticeCode) {this.noticeCode = noticeCode;return this;}public Builder setSignature(String signature) {this.signature = signature;return this;}public PdfPageEventListener build() {return new PdfPageEventListener(headerFontSize, headerWidth, headerHeight, headerBaseFont, headerFont, noticeCode, signature);}} }2、實(shí)踐
比如我們模擬用戶信息打印。
創(chuàng)建用戶信息實(shí)體類UserModel
public class UserModel {private String name;private int age;private String sex;private String nativePlace;private String national;private String education;private String remark;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getNativePlace() {return nativePlace;}public void setNativePlace(String nativePlace) {this.nativePlace = nativePlace;}public String getNational() {return national;}public void setNational(String national) {this.national = national;}public String getEducation() {return education;}public void setEducation(String education) {this.education = education;}public String getRemark() {return remark;}public void setRemark(String remark) {this.remark = remark;} }創(chuàng)建適用于用戶信息打印的pdf構(gòu)建實(shí)現(xiàn)類UserInfoPdfCreator
import com.demo.openpdfdemo.model.UserModel; import com.demo.openpdfdemo.pdfCreator.core.AbstractPdfCreator; import com.demo.openpdfdemo.pdfCreator.core.HtmlParserUtil; import com.lowagie.text.Chunk; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Font; import com.lowagie.text.Paragraph; import com.lowagie.text.pdf.PdfPCell; import com.lowagie.text.pdf.PdfPTable; import org.springframework.util.CollectionUtils;import java.io.IOException; import java.util.List; import java.util.Map;/*** 用戶信息導(dǎo)出為pdf*/ public class UserInfoPdfCreator extends AbstractPdfCreator {@Overridepublic void execute(Map<String, Object> map) throws DocumentException, IOException {//map中可以存放實(shí)體類信息,以及其他各種邏輯數(shù)據(jù)信息等UserModel user = (UserModel) map.get("data");Font titleFont = new Font(baseFont, 14, Font.BOLD);Paragraph title = new Paragraph("用戶信息表", titleFont);title.setAlignment(Element.ALIGN_CENTER);title.setSpacingAfter(10F);document.add(title);Paragraph paragraphText = new Paragraph();Font font1 = new Font(baseFont, fontSize, Font.NORMAL);paragraphText.add(new Chunk("此表為用戶基本信息,請(qǐng)查看", font1));paragraphText.setAlignment(Element.ALIGN_LEFT);paragraphText.setFirstLineIndent(fontSize * 2);document.add(paragraphText);PdfPTable table = new PdfPTable(4);table.setTotalWidth(530);table.setWidths(new int[]{20, 30, 22, 28});table.setSpacingBefore(20);table.setWidthPercentage(100);table.setLockedWidth(true);Paragraph p1 = new Paragraph("姓名", font);PdfPCell cell1 = new PdfPCell(p1);cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);table.addCell(cell1);Paragraph p2 = new Paragraph(user.getName(), font);PdfPCell cell2 = new PdfPCell(p2);cell2.setVerticalAlignment(Element.ALIGN_MIDDLE);table.addCell(cell2);Paragraph p3 = new Paragraph("年齡", font);PdfPCell cell3 = new PdfPCell(p3);cell3.setVerticalAlignment(Element.ALIGN_MIDDLE);table.addCell(cell3);Paragraph p4 = new Paragraph(String.valueOf(user.getAge()), font);PdfPCell cell4 = new PdfPCell(p4);cell4.setVerticalAlignment(Element.ALIGN_MIDDLE);table.addCell(cell4);Paragraph p5 = new Paragraph("性別", font);PdfPCell cell5 = new PdfPCell(p5);cell5.setVerticalAlignment(Element.ALIGN_MIDDLE);table.addCell(cell5);Paragraph p6 = new Paragraph(user.getSex(), font);PdfPCell cell6 = new PdfPCell(p6);cell6.setVerticalAlignment(Element.ALIGN_MIDDLE);table.addCell(cell6);Paragraph p7 = new Paragraph("籍貫", font);PdfPCell cell7 = new PdfPCell(p7);cell7.setVerticalAlignment(Element.ALIGN_MIDDLE);table.addCell(cell7);Paragraph p8 = new Paragraph(user.getSex(), font);PdfPCell cell8 = new PdfPCell(p8);cell8.setVerticalAlignment(Element.ALIGN_MIDDLE);table.addCell(cell8);Paragraph p9 = new Paragraph("民族", font);PdfPCell cell9 = new PdfPCell(p9);cell9.setVerticalAlignment(Element.ALIGN_MIDDLE);table.addCell(cell9);Paragraph p10 = new Paragraph(user.getSex(), font);PdfPCell cell10 = new PdfPCell(p10);cell10.setVerticalAlignment(Element.ALIGN_MIDDLE);table.addCell(cell10);Paragraph p11 = new Paragraph("學(xué)歷", font);PdfPCell cell11 = new PdfPCell(p11);cell11.setVerticalAlignment(Element.ALIGN_MIDDLE);table.addCell(cell11);Paragraph p12 = new Paragraph(user.getSex(), font);PdfPCell cell12 = new PdfPCell(p12);cell12.setVerticalAlignment(Element.ALIGN_MIDDLE);table.addCell(cell12);Paragraph p13 = new Paragraph("備注", font);PdfPCell cell13 = new PdfPCell(p13);cell13.setVerticalAlignment(Element.ALIGN_MIDDLE);table.addCell(cell13);PdfPCell cell14 = new PdfPCell();List<Element> elements = HtmlParserUtil.htmlParseToElementList(user.getRemark(), font);if (!CollectionUtils.isEmpty(elements)) {for (Element element : elements) {cell14.addElement(element);}}cell14.setColspan(3);table.addCell(cell14);table.setSplitLate(false);document.add(table);} }實(shí)際項(xiàng)目中有的字段信息為富文本類型的,數(shù)據(jù)庫中存儲(chǔ)的是html片段,但這個(gè)跟整個(gè)html轉(zhuǎn)pdf還不一樣,比如這里的用戶的備注信息,這里要求這個(gè)備注信息插入到pdf中,其他字段不是html片段。官方提供的是通過HTMLWorker來實(shí)現(xiàn),看源碼,提供的注釋也是少之甚少啊。
創(chuàng)建HtmlParserUtil工具類:
以上代碼可以看出對(duì)font進(jìn)行了相關(guān)處理,若不處理的話,中文是不能正常顯示的。很多人就疑問itext可針對(duì)html進(jìn)行字體注冊(cè)和樣式設(shè)置,這個(gè)沒有嗎?其實(shí)是有的;
再看源碼,第二個(gè)參數(shù)就是存儲(chǔ)樣式的,第三個(gè)參數(shù)是自定義字體注冊(cè)的實(shí)現(xiàn)類
worker.setInterfaceProps(interfaceProps);我們進(jìn)一步看源碼
可以看到FontProvider是根據(jù)需要進(jìn)行自定義實(shí)現(xiàn)類,它默認(rèn)有一個(gè)實(shí)現(xiàn)類
這里面有很多方法,可以通過各種方式來將本地或者指定路徑的字體加載進(jìn)來,如
我嘗試把本地的其他中文字體加載進(jìn)來后,并且在html標(biāo)簽上設(shè)置屬性font-family后,還是pdf無法顯示中文,這也是我為啥在工具類中直接獲取解析后的信息直接替換的原因。
好,繼續(xù)操作,創(chuàng)建UserService ,方法為printUserInfo,用戶信息可以自行實(shí)現(xiàn)加載,這里是模擬。
import com.demo.openpdfdemo.model.UserModel; import com.demo.openpdfdemo.pdfCreator.PdfPageEventListener; import com.demo.openpdfdemo.pdfCreator.UserInfoPdfCreator; import com.demo.openpdfdemo.pdfCreator.core.AbstractPdfCreator; import org.springframework.stereotype.Service;import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.time.LocalDate; import java.util.HashMap; import java.util.Map;@Service public class UserService {/*** 用戶信息打印** @param response* @throws IOException*/public void printUserInfo(HttpServletResponse response) throws IOException {UserModel model = new UserModel();model.setName("張三");model.setAge(12);model.setEducation("本科");model.setNational("漢族");model.setSex("男");model.setNativePlace("北京市");model.setRemark("<p>此人學(xué)習(xí)習(xí)慣很好</p><p><strong>非常優(yōu)秀</strong></p>愛好<ul><li>籃球</li><li>乒乓球</li></ul><table border=\"1\" style=\"border-collapse: collapse\"><tr><th style=\"width: 30%;color: aquamarine\">畢業(yè)學(xué)校</th> <th style=\"width: 30%\">專業(yè)</th> </tr><tr><td style=\"width: 30%\">清華</td> <td style=\"width: 30%\">計(jì)算機(jī)</td> </tr></table>");Map<String, Object> map = new HashMap<>();map.put("data", model);String signature = "簽字:________________" + "日期:" + LocalDate.now();PdfPageEventListener listener = PdfPageEventListener.build().setNoticeCode("0001").setSignature(signature).build();AbstractPdfCreator pdfCreator = new UserInfoPdfCreator();ByteArrayOutputStream outputStream = pdfCreator.init(listener).creator(map);response.reset();response.setHeader("Content-Type", "application/pdf");response.setHeader("content-disposition", "attachment;filename=111.pdf");response.setContentLength(outputStream.size());OutputStream output = response.getOutputStream();outputStream.writeTo(output);output.flush();output.close();} }創(chuàng)建controller :UserController
import com.demo.openpdfdemo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletResponse; import java.io.IOException;@Controller @RequestMapping("/user") public class UserController {@Autowiredprivate UserService userService;@RequestMapping(path = "/userPrint", method = RequestMethod.POST)@ResponseBodypublic void userPrint(HttpServletResponse response) {try {userService.printUserInfo(response);} catch (IOException e) {e.printStackTrace();}}@RequestMapping("/hello")public String index(){return "index";} }創(chuàng)建一個(gè)頁面,模擬一下下載操作,創(chuàng)建index.html,默認(rèn)是加載templetes文件夾的頁面,文件夾沒有自行創(chuàng)建即可。
application.yml配置,我這里簡(jiǎn)單
server:port: 8080啟動(dòng)服務(wù),訪問
點(diǎn)擊下載,看一下內(nèi)容。備注里的信息全是中文都可正常顯示。
gitee項(xiàng)目地址
鏈接: https://gitee.com/yang1112/openPdfDemo.git
關(guān)于源碼本人還在研究中,后續(xù)會(huì)根據(jù)實(shí)際用到的進(jìn)行相關(guān)代碼解析和案例講解
總結(jié)
以上是生活随笔為你收集整理的OpenPdf组件替换Itext方案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mac VirtualBox安装旧版ub
- 下一篇: pdfFactory Pro 不能被安装