由於工作需要,要實現后端根據模板動態填充數據生成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 key="net.sf.jasperreports.html">'宋體', Arial, Helvetica, sans-serif</