Spring Boot集成JasperReports生成PDF文档
由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲染生成PDF文档。本人文采欠缺,写作能力差,下面粗略的介绍其使用步骤,若有不对的地方,望大家莫喷,谢谢!
一、使用Ireport designer 5.6设计模板
ireport的使用由于时间关系不便多说,设计好之后,将其进行编译生成jasper文件,然后将其拷贝放置于项目某个目录下,以供访问获取该文件。
二、在Spring Boot项目中引入依赖包
<!-- jasperreports-->
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports-fonts</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-pdfa</artifactId>
<version>5.5.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.11</version>
</dependency>
三、自定义spring mvc通用导出PDF视图类PdfReportView(继承自AbstractView )
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import org.springframework.web.servlet.view.AbstractView;
public class PdfReportView extends AbstractView {
private static final String CONTENT_TYPE = "application/pdf";
private String templatePath;
private String exportFileName;
public PdfReportView(String templatePath, String exportFileName) {
this.templatePath = templatePath;
if (exportFileName != null) {
try {
exportFileName = URLEncoder.encode(exportFileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
this.exportFileName = exportFileName;
setContentType(CONTENT_TYPE);
}
protected Map<String, Object> getParamsMap(Map<String, Object> map) throws Exception {
Map<String, Object> params = new HashMap<>();
for (String key : map.keySet()) {
Object val = map.get(key);
if (val instanceof JRDataSource) {
continue;
} else {
params.put(key, val);
}
}
return params;
}
protected JRDataSource getDataSource(Map<String, Object> map) throws Exception {
for (String key : map.keySet()) {
Object val = map.get(key);
if (val instanceof JRDataSource) {
return (JRDataSource) map.get(key);
}
}
return new JREmptyDataSource();
}
@Override
protected void renderMergedOutputModel(Map<String, Object> map,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
response.setCharacterEncoding("utf-8");
response.setContentType(getContentType());
//response.setContentType("application/octet-stream");
response.setHeader("content-disposition", "attachment;filename=" + exportFileName + ".pdf");
try (InputStream inputStream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(templatePath)) {
try (OutputStream ouputStream = response.getOutputStream()) {
JasperPrint jasperPrint = JasperFillManager
.fillReport(inputStream, getParamsMap(map), getDataSource(map));
JasperExportManager.exportReportToPdfStream(jasperPrint, ouputStream);
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
四、spring mvc调用案例
Map<String, Object> map = new HashMap<>();
List<Map<String,Object>> dataList = ....
map.put("users", new JRMapCollectionDataSource(dataList));
map.put("title", "报表名称");
return new ModelAndView(new PdfReportView("templates/report/resume.jasper", "professors"),map);
五、解决linux下宋体渲染问题
1、在src/main/resources路径下新建jasperreports_extension.properties文件,内容如下:
net.sf.jasperreports.awt.ignore.missing.font=true
net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.dejavu=fonts/fonts.xml
2、在src/main/resources路径下新建fonts目录,并新建fonts.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
<fontFamily name="DejaVu Sans">
<normal>net/sf/jasperreports/fonts/dejavu/DejaVuSans.ttf</normal>
<bold>net/sf/jasperreports/fonts/dejavu/DejaVuSans-Bold.ttf</bold>
<italic>net/sf/jasperreports/fonts/dejavu/DejaVuSans-Oblique.ttf</italic>
<boldItalic>net/sf/jasperreports/fonts/dejavu/DejaVuSans-BoldOblique.ttf</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Sans', Arial, Helvetica, sans-serif</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Sans', Arial, Helvetica, sans-serif</export>
</exportFonts>
<!--
<locales>
<locale>en_US</locale>
<locale>de_DE</locale>
</locales>
-->
</fontFamily>
<fontFamily name="DejaVu Serif">
<normal>net/sf/jasperreports/fonts/dejavu/DejaVuSerif.ttf</normal>
<bold>net/sf/jasperreports/fonts/dejavu/DejaVuSerif-Bold.ttf</bold>
<italic>net/sf/jasperreports/fonts/dejavu/DejaVuSerif-Italic.ttf</italic>
<boldItalic>net/sf/jasperreports/fonts/dejavu/DejaVuSerif-BoldItalic.ttf</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Serif', 'Times New Roman', Times, serif</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Serif', 'Times New Roman', Times, serif</export>
</exportFonts>
</fontFamily>
<fontFamily name="DejaVu Sans Mono">
<normal>net/sf/jasperreports/fonts/dejavu/DejaVuSansMono.ttf</normal>
<bold>net/sf/jasperreports/fonts/dejavu/DejaVuSansMono-Bold.ttf</bold>
<italic>net/sf/jasperreports/fonts/dejavu/DejaVuSansMono-Oblique.ttf</italic>
<boldItalic>net/sf/jasperreports/fonts/dejavu/DejaVuSansMono-BoldOblique.ttf</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Sans Mono', 'Courier New', Courier, monospace</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Sans Mono', 'Courier New', Courier, monospace</export>
</exportFonts>
</fontFamily>
<fontFamily name="SansSerif">
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Sans', Arial, Helvetica, sans-serif</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Sans', Arial, Helvetica, sans-serif</export>
</exportFonts>
</fontFamily>
<fontFamily name="Serif">
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Serif', 'Times New Roman', Times, serif</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Serif', 'Times New Roman', Times, serif</export>
</exportFonts>
</fontFamily>
<fontFamily name="Monospaced">
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Sans Mono', 'Courier New', Courier, monospace</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Sans Mono', 'Courier New', Courier, monospace</export>
</exportFonts>
</fontFamily>
<fontFamily name="宋体">
<normal>fonts/simsun.ttf</normal>
<bold>fonts/simsun.ttf</bold>
<italic>fonts/simsun.ttf</italic>
<boldItalic>fonts/simsun.ttf</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export