最近,項目上要做個打印的東西,還要預覽。我想就直接生成pdf預覽,然后用戶選擇打印
於是,昨天找了找資料。一般用itext 進行轉pdf。於是我就用springboot試了試,代碼比較簡單,現在只是簡單的一個實現。
整體流程如下
- 1.獲取數據(比如從數據庫獲取數據)
- 2.通過freemarker 渲染頁面
- 3.將渲染的頁面進行轉換為pdf,放在本地
- 4.讀取pdf,實現預覽
主要代碼
pom文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</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-web</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf.tool/xmlworker -->
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.13</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
PdfController代碼
package com.kevin.pdf_demo.controller;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
/**
* @author: kevin
* @Date: 2018/11/16
*/
@RestController
public class PdfController {
@Value("${DEST}")
private String dest;
@Value("${HTML}")
private String html;
@Value("${FONT}")
private String font;
private static Configuration freemarkerCfg = null;
@RequestMapping(value = "helloPdf")
public void showPdf(HttpServletResponse response) throws IOException, DocumentException {
//需要填充的數據
Map<String, Object> data = new HashMap<>(16);
data.put("name", "kevin");
String content = freeMarkerRender(data,html);
//創建pdf
createPdf(content, dest);
// 讀取pdf並預覽
readPdf(response);
}
public void createPdf(String content,String dest) throws IOException, DocumentException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
// step 3
document.open();
// step 4
XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontImp.register(font);
XMLWorkerHelper.getInstance().parseXHtml(writer, document,
new ByteArrayInputStream(content.getBytes("UTF-8")), null, Charset.forName("UTF-8"), fontImp);
// step 5
document.close();
}
/**
* freemarker渲染html
*/
public String freeMarkerRender(Map<String, Object> data, String htmlTmp) {
Writer out = new StringWriter();
try {
// 獲取模板,並設置編碼方式
setFreemarkerCfg();
Template template = freemarkerCfg.getTemplate(htmlTmp);
template.setEncoding("UTF-8");
//將合並后的數據和模板寫入到流中,這里使用的字符流
template.process(data, out);
out.flush();
return out.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
return null;
}
/**
* 設置freemarkerCfg
*/
private void setFreemarkerCfg() {
freemarkerCfg = new Configuration();
//freemarker的模板目錄
try {
freemarkerCfg.setDirectoryForTemplateLoading(new ClassPathResource("template").getFile());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 讀取本地pdf,這里設置的是預覽
*/
private void readPdf(HttpServletResponse response) {
response.reset();
response.setContentType("application/pdf");
try {
File file = new File(dest);
FileInputStream fileInputStream = new FileInputStream(file);
OutputStream outputStream = response.getOutputStream();
IOUtils.write(IOUtils.toByteArray(fileInputStream), outputStream);
response.setHeader("Content-Disposition",
"inline; filename= file");
outputStream.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
運行效果
設置頭信息使瀏覽器下載文件或預覽
強制瀏覽器下載
response.setHeader("content-disposition", "attachment;filename=" + realName);
瀏覽器嘗試打開,支持office online或瀏覽器預覽pdf功能
response.setHeader("content-disposition", "inline;filename=" + realName);
完整代碼 : github
玩的開心!