Spring Boot 集成 JasperReports
导入依赖 pom.xml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports</artifactId> <version>7.0.1</version> <exclusions> <exclusion> <groupId>com.lowagie</groupId> <artifactId>itext</artifactId> </exclusion> </exclusions> </dependency>
<dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports-pdf</artifactId> <version>7.0.1</version> </dependency>
<dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports-fonts</artifactId> <version>7.0.1</version> </dependency>
|
基础设施
接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.JRException; import org.springframework.http.ResponseEntity; import java.sql.SQLException; import java.util.Map;
public interface JasperService {
ResponseEntity<byte[]> PDF(String fileName, Map<String, Object> parameters, JRDataSource dataSource) throws JRException, SQLException; }
|
实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| import cn.hutool.core.lang.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.sf.jasperreports.engine.*; import net.sf.jasperreports.engine.util.JRLoader; import org.springframework.http.*; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; import javax.sql.DataSource; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.sql.SQLException; import java.util.Map; import java.util.concurrent.TimeUnit;
@Slf4j @Service @RequiredArgsConstructor public class JasperServiceImpl implements JasperService { private final DataSource systemDataSource;
@Override public ResponseEntity<byte[]> PDF(String fileName, Map<String, Object> parameters, JRDataSource dataSource) throws JRException, SQLException { JasperPrint jasperPrint = FillData(fileName, parameters, dataSource); byte[] bytes = JasperExportManager.exportReportToPdf(jasperPrint); HttpHeaders header = new HttpHeaders(); header.setContentType(MediaType.APPLICATION_PDF); header.setCacheControl(CacheControl .maxAge(10, TimeUnit.MINUTES) .mustRevalidate()); header.setContentDisposition( ContentDisposition.builder("inline") .filename("report_" + UUID.fastUUID() + ".pdf") .build() ); return ResponseEntity.ok() .headers(header) .body(bytes); }
private JasperPrint FillData(String fileName, Map<String, Object> parameters, JRDataSource dataSource) throws JRException, SQLException { InputStream inputStream = getClass().getClassLoader().getResourceAsStream(fileName); if (ObjectUtils.isEmpty(inputStream)) log.error("Error loading file {}", fileName);
JasperReport jasperReport = (JasperReport) JRLoader.loadObject(inputStream);
JasperPrint jasperPrint; if (!ObjectUtils.isEmpty(dataSource)) jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource); else jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, systemDataSource.getConnection()); return jasperPrint; } }
|
配置文件
在 resources
目录下创建字体目录 fonts
。
fonts/fonts.xml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <?xml version="1.0" encoding="UTF-8"?>
<fontFamilies> <fontFamily name="华文宋体"> <normal>fonts/STSONG.TTF</normal> <bold>fonts/STSONG.TTF</bold> <italic>fonts/STSONG.TTF</italic> <boldItalic>fonts/STSONG.TTF</boldItalic> <pdfEncoding>Identity-H</pdfEncoding> <pdfEmbedded>true</pdfEmbedded> <exportFonts> <export key="net.sf.jasperreports.html">'华文宋体', Arial, Helvetica, sans-serif</export> <export key="net.sf.jasperreports.xhtml">'华文宋体', Arial, Helvetica, sans-serif</export> </exportFonts> </fontFamily> </fontFamilies>
|
注册字体
创建配置文件,必须定义为 jasperreports.properties
:
1 2 3
|
net.sf.jasperreports.awt.ignore.missing.font=true
|
创建配置文件,必须定义为 jasperreports_extension.properties
:
1 2 3 4
| net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.lobstertwo=fonts/fonts.xml
|
注意:以上两个配置文件不能合成一个配置文件!!
创建 PDF 模板
xxx.jrxml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
| <?xml version="1.0" encoding="UTF-8"?> <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="lq_item" language="java" pageWidth="842" pageHeight="595" orientation="Landscape" columnWidth="802" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="d231d38f-0c4c-456f-8a9a-6418352f4484" whenNoDataType="AllSectionsNoDetail" isIgnorePagination="false">
<style name="Title" fontName="华文宋体" fontSize="30" isBold="true" hTextAlign="Center" vTextAlign="Middle"/> <style name="SubTitle" fontName="华文宋体" fontSize="16" hTextAlign="Center" vTextAlign="Middle"/> <style name="ColumnHeader" fontName="华文宋体" fontSize="14" isBold="true" hTextAlign="Center" vTextAlign="Middle"/> <style name="Detail" fontName="华文宋体" fontSize="14" hTextAlign="Center" vTextAlign="Middle"/>
<parameter name="title" class="java.lang.String"/> <parameter name="time" class="java.lang.String"/> <field name="id" class="java.lang.Integer"/> <field name="account" class="java.lang.String"/> <field name="name" class="java.lang.String"/> <field name="memo" class="java.lang.String"/> <field name="ghInfo" class="java.lang.String"/>
<background> <band splitType="Stretch"/> </background>
<title> <band height="100"> <textField> <reportElement x="0" y="10" width="802" height="40" style="Title"/> <textFieldExpression><![CDATA[$P{title}]]></textFieldExpression> </textField> <textField> <reportElement x="0" y="60" width="802" height="30" style="SubTitle"/> <textFieldExpression><![CDATA["时间:" + $P{time}]]></textFieldExpression> </textField> </band> </title>
<pageHeader> <band height="0"/> </pageHeader>
<columnHeader> <band height="40"> <staticText> <reportElement x="17" y="0" width="121" height="40" style="ColumnHeader"/> <box> <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> </box> <text><![CDATA[序号]]></text> </staticText> <staticText> <reportElement x="138" y="0" width="121" height="40" style="ColumnHeader"/> <box> <pen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> </box> <text><![CDATA[账号/联系电话]]></text> </staticText> <staticText> <reportElement x="259" y="0" width="121" height="40" style="ColumnHeader"/> <box> <pen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> </box> <text><![CDATA[姓名]]></text> </staticText> <staticText> <reportElement x="380" y="0" width="151" height="40" style="ColumnHeader"/> <box> <pen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> </box> <text><![CDATA[人员备注]]></text> </staticText> <staticText> <reportElement x="531" y="0" width="240" height="40" style="ColumnHeader"/> <box> <pen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> </box> <text><![CDATA[衣物信息]]></text> </staticText> </band> </columnHeader>
<detail> <band height="30"> <textField> <reportElement x="17" y="0" width="121" height="30" style="Detail"/> <box> <pen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> </box> <textFieldExpression><![CDATA[$F{id}]]></textFieldExpression> </textField> <textField> <reportElement x="138" y="0" width="121" height="30" style="Detail"/> <box> <pen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> </box> <textFieldExpression><![CDATA[$F{account}]]></textFieldExpression> </textField> <textField> <reportElement x="259" y="0" width="121" height="30" style="Detail"/> <box> <pen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> </box> <textFieldExpression><![CDATA[$F{name}]]></textFieldExpression> </textField> <textField> <reportElement x="380" y="0" width="151" height="30" style="Detail"/> <box> <pen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> </box> <textFieldExpression><![CDATA[$F{memo}]]></textFieldExpression> </textField> <textField> <reportElement x="531" y="0" width="240" height="30" style="Detail"/> <box> <pen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/> </box> <textFieldExpression><![CDATA[$F{ghInfo}]]></textFieldExpression> </textField> </band> </detail>
<columnFooter> <band height="0"/> </columnFooter>
<pageFooter> <band height="0"> </band> </pageFooter>
<summary> <band height="0"/> </summary> </jasperReport>
|

将 .jrxml
文件复制到 Jaspersoft Studio 中并编译成 .jasper
文件,然后将 .jasper
文件拖入到 resources
目录中。
Resources 目录层级结构
渲染数据并导出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| import lombok.RequiredArgsConstructor; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.sql.SQLException; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map;
@RestController @RequiredArgsConstructor @RequestMapping("/jasper") public class JasperController { private final JasperService jasperService;
@GetMapping("/pdf") public ResponseEntity<byte[]> PDF() throws JRException, SQLException { String template = "jasper/xxx.jasper"; Map<String, Object> parameters = new HashMap<>(); parameters.put("title", "Test Table"); parameters.put("time", "2999-10-12"); List<Map<String, Object>> data = Arrays.asList( new HashMap<>() {{ put("id", 1); put("account", "002"); put("name", "name1"); put("memo", "memo1"); put("ghInfo", "info1"); }}, new HashMap<>() {{ put("id", 2); put("account", "002"); put("name", "name2"); put("memo", "memo2"); put("ghInfo", "info2"); }} ); JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(data); return jasperService.PDF(template, parameters, dataSource); } }
|
