当下项目中需要用户定制导出 PDF,以便快速的适应客户的需求变化。后来在网上查资料发现可以使用 JasperReports + Jaspersoft Studio工具来实现可配置的报表。
1.JasperReports 介绍
JasperReports 是一个非常强大,易用的开源报表引擎,它是用 Java 编写的。它可以通过各种各样的数据源来生成像素级的文档,这些文档都可以查看,打印以及导出(文档格式包括 HTML、PDF、Excel、Word 等等)。
1.1.Jaspersoft Studio
Jaspersoft Studio 是一个设计报表模板的工具,我们通过它来设计需要使用报表的模板。 下载地址
使用教程
将 .jrxml
文件复制到项目的 resources/pdf/templates
目录下。
下载示例文件:https://wwa.lanzous.com/i7Sfejetw7g
2.导入 jasperreports
<!-- https://mvnrepository.com/artifact/net.sf.jasperreports/jasperreports -->
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.14.0</version>
</dependency>
3.配置字体
配置字体指的是在设计 PDF 模板时使用的字体需要配置到项目内,如果不配置将会导出时不显示中文字符。
3.1.首先在 resources
创建文件 jasperreports_extension.properties
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
3.2.然后在 resources/fonts
创建 fonts.xml
<?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">'华文宋体',Helvetica,sans-serif</export>
<export key="net.sf.jasperreports.xhtml">'华文宋体',Helvetica,sans-serif</export>
</exportFonts>
</fontFamily>
<fontFamily name="思源黑体">
<normal>fonts/SourceHanSansCN.ttf</normal>
<bold>fonts/SourceHanSansCN.ttf</bold>
<italic>fonts/SourceHanSansCN.ttf</italic>
<boldItalic>fonts/SourceHanSansCN.ttf</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export key="net.sf.jasperreports.html">'思源黑体',Arial</export>
<export key="net.sf.jasperreports.xhtml">'思源黑体',Arial</export>
</exportFonts>
</fontFamily>
</fontFamilies>
原理分析:https://www.cnblogs.com/xyyz120/p/12681258.html
3.3.复制字体文件(必须是.ttf格式)
4. 编写Java代码
package com.hsmus;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
public class PDFMaker {
public static void main(String[] args) throws JRException, IOException {
String sourceFilePath = PDFMaker.class.getResource("/pdf_template/demo1.jrxml").getPath();
String targetFilePath = PDFMaker.class.getResource("/pdf_template/").getPath() + "demo1.jasper";
compileXML(sourceFilePath, targetFilePath);
writeByJavaBean(targetFilePath);
}
/**
* 编译jrxml文件,如果修改过jrxml文件,务必删除已经编译过的jasper
*
* @param sourceFilePath jrxml文件路径
* @param targetFilePath jasper目标文件路径
*/
private static void compileXML(String sourceFilePath, String targetFilePath) throws JRException {
File file = new File(targetFilePath);
if (!file.exists()) {
System.out.println("jasper文件不存在,正在编译...");
JasperCompileManager.compileReportToFile(sourceFilePath, targetFilePath);
} else {
System.out.println("jasper文件存在,跳过编译...");
}
}
/**
* 通过填充数据生成PDF
* @param targetFilePath jasper目标文件路径
* @throws JRException
* @throws IOException
*/
private static void writeByJavaBean(String targetFilePath) throws JRException, IOException {
System.out.println("正在填充数据...");
// 构造数据
Map<String, Object> parameter = new HashMap<String, Object>();
parameter.put("username", "王小明");
parameter.put("business_name", "5G高速通信网络开通");
parameter.put("item_amount", "500.00");
List<Map> list = new ArrayList<Map>();
Map<String, Object> itemMap = new HashMap<String, Object>();
itemMap.put("item_id", "KT0001");
itemMap.put("item_name", "业务开通");
itemMap.put("item_price", 200.00f);
itemMap.put("item_count", 1);
itemMap.put("item_amount", 1 * 200f);
itemMap.put("item_remark", "一年的使用");
list.add(itemMap);
itemMap = new HashMap<String, Object>();
itemMap.put("item_id", "KT0002");
itemMap.put("item_name", "香蕉手机购买");
itemMap.put("item_price", 9000.00f);
itemMap.put("item_count", 1);
itemMap.put("item_amount", 1 * 9000f);
itemMap.put("item_remark", "三年免费换新");
list.add(itemMap);
parameter.put("all_amount", "19900.00");
JasperPrint jasperPrint = JasperFillManager.fillReport(
targetFilePath,
parameter,
new JRBeanCollectionDataSource(list)
);
System.out.println("正在输出...");
String pdfPath = "D:\\test" + new Date().getTime() + ".pdf";
// 1.直接输出到文件,适合本地操作
// JasperExportManager.exportReportToPdfFile(jasperPrint, pdfPath);
// 2.输出到fileOutputStream,方便改造成在网站上导出
FileOutputStream fileOutputStream = new FileOutputStream(pdfPath);
JasperExportManager.exportReportToPdfStream(jasperPrint, fileOutputStream);
fileOutputStream.close();
System.out.println("输出完成:" + pdfPath);
/*
// 网站输出记得设置响应头信息
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment;filename=report.pdf");
*/
}
}
5.结果
扫码在手机查看
您没有登录或者此篇文章不允许评论哟~~
暂无评论