一、前言
? ? ? ? 上一篇我們介紹了導出word,既然有了導出word,那么到處pdf也將會出現,導出word和pdf基本上是配套的需求,跑不了,那么本次我就簡單介紹一下導出pdf。
二、代碼實現
? ? ? ? 2.1、依賴引入
? ? ? ? 導出pdf是基于documents4j實現的,需要引入一些依賴,pom文件的話大家以實際情況編寫,比如小永哥本地只加了documents4j-local和documents4j-transformer-msoffice-word就好了,如果只引這兩個報不全的話,建議大家講依賴包都documents4j都加到pom文件中,除了documents4j還有一個org下的zeroturnaround依賴,詳情請看下圖。
? ? ? ? 2.2、代碼實現
package com.relation;import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import java.io.*;
public class PdfTest {public static void convert(String inputPath, String outputPath) throws Exception {File inputFile = new File(inputPath);File outputFile = new File(outputPath);try (InputStream docx = new FileInputStream(inputFile);OutputStream pdf = new FileOutputStream(outputFile)) {IConverter converter = LocalConverter.builder().build();converter.convert(docx).as(DocumentType.DOCX).to(pdf).as(DocumentType.PDF).execute();converter.shutDown();}}public static void main(String[] args) {try {convert("C:\\Users\\ASP.NET\\Downloads\\導出測試文件.docx", "C:\\Users\\ASP.NET\\Downloads\\導出測試文件.pdf");} catch (Exception e) {e.printStackTrace();}}
}
????????
? ? ? ? 2.3、web實現
? ? ? ? 我們通過2.2步驟可以看到,已經能實現了,我們再來看看開發過程中的寫法,其實是大同小異,都是對文件流的操作而已。我們看代碼。
@PostMapping("/exportPdfFile")public void exportPdfFile(HttpServletResponse response){//創建XWPFDocumentXWPFDocument doc = getXWPFDocument();ServletOutputStream outputStream = null;try{//獲取doc的輸入流ByteArrayOutputStream baos = new ByteArrayOutputStream();doc.write(baos);InputStream in = new ByteArrayInputStream(baos.toByteArray());outputStream = response.getOutputStream();response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");response.setHeader("Content-Disposition", "attachment; filename="+ URLEncoder.encode("web測試導出.pdf", "UTF-8"));IConverter converter = LocalConverter.builder().build();converter.convert(in).as(DocumentType.DOCX).to(outputStream).as(DocumentType.PDF).execute();converter.shutDown();}catch (Exception e){log.error(e.getMessage(),e);throw new RuntimeException("導出異常");}finally {if(Objects.nonNull(outputStream)){try {outputStream.close();doc.close();}catch (Exception e){}}}}private XWPFDocument getXWPFDocument(){try {Resource resource = new ClassPathResource("model/導出模板.docx");XWPFDocument doc = new XWPFDocument(resource.getInputStream());//獲取段落List<XWPFParagraph> paragraphs = doc.getParagraphs();for (XWPFParagraph paragraph : paragraphs) {//從段落中獲取書簽List<CTBookmark> bookmarkStartList = paragraph.getCTP().getBookmarkStartList();for (CTBookmark ctBookmark : bookmarkStartList) {String ctBookmarkName = ctBookmark.getName();if("exportTitle".equals(ctBookmarkName)){// 清除原有內容paragraph.getRuns().forEach(run -> run.setText("", 0));// 添加新內容paragraph.createRun().setText("導出測試標題!!");}if("tableTitle".equals(ctBookmarkName)){// 清除原有內容paragraph.getRuns().forEach(run -> run.setText("", 0));// 添加新內容paragraph.createRun().setText("測試導出表格標題!!");}if("tableInfo".equals(ctBookmarkName)){// 在書簽位置創建表格XWPFTable table = doc.insertNewTbl(paragraph.getCTP().newCursor());//刪除默認行table.removeRow(0);//插入3行for (int i = 0; i < 3; i++) {table.createRow();}List<XWPFTableRow> rows = table.getRows();String[] headers = {"序號","姓名","年齡","城市"};XWPFTableRow headerRow = table.getRow(0);for(int i=0; i<headers.length; i++) {headerRow.createCell().setText(headers[i]);}// 添加數據行String[][] data = {{"1","小永哥","18","北京"},{"2","胡彪","45","吉林"}};for (int i = 0; i < data.length; i++) {XWPFTableRow row = table.getRow(i+1);String[] rowData = data[i];for(int j=0; j<rowData.length; j++) {row.createCell().setText(rowData[j]);}}}}}return doc;}catch (Exception e){log.error(e.getMessage(),e);return null;}}
? ? ? ? 基于接口形式的代碼我們也演示完了,基本上導出pdf的代碼就到此了,核心思路其實是根據word文件生成pdf,簡單來說就是word轉pdf。
三、結語
? ? ? ? 本期word轉pdf看似很完美,其實還差最核心的一步,就是我們在第二章節的代碼實現,目前只能運行在windows環境,如果一旦代碼要部署到生產環境,那么就無法使用了,因為word轉pdf需要依賴LiberOffice,Windows環境大家基本上都會安裝office,所以并未感知到office的作用,而生產環境是linux的話,就需要再安裝一套基于linux的LiberOffice,這個問題小永哥暫時還未解決,等解決后,小永哥會再補充一篇,本期暫時就到這里了,晚安......