1 Star 0 Fork 11

diycp2015 / EasyPrint

forked from 猎隼丶止戈 / EasyPrint 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MulanPSL-2.0

EasyPrint

Lodop + JasperReports 打印模块

前言

Lodop

Lodop是什么?

有人说她是Web打印控件,因为她能打印、在浏览器中以插件的形式出现,用简单一行语句就把整个网页打印出来; 有人说她是打印编程接口,因为她介于浏览器和打印设备之间,是个通道和桥梁,几乎能想到的打印控制事项都能做到; 有人说她是JavaScript的扩展,因为她所有功能就那么几个语句,和JS语法一样,一看就明白个究竟; 有人说她是报表打印工具,因为那个add_print_table语句把报表统计的那点事弄了个明明白白; 有人说她是条码打印工具,因为用了她再也不用后台生成条码图片了,前端一行指令就动态输出清晰准确的条码,一维二维都行; 有人说她是图表打印工具,因为用她能输出几乎能想象的任何图表,虽然没那么豪华,但什么饼图、折线图、柱图甚至复合图等等都不在话下; 有人说她是个小玩意,因为她体积太小了,才2M多,她所包含的其中任何一个对照工具都是她的好几倍(例如条码打印控件、图表控件等); 有人说她是套打教案,因为以Lodop+JS实现套打这种模式,在网上已被吵吵为教科书般的解决方案; 有人说她是Web打印控件的“终结者”,因为接触“她”后再不想别的“她”; 有人说她就是一个Web编程小工具,因为有了她,在BS下的打印终于像cs下那种随意而高效了; 但我们说,她是全国1000多家软件公司的智慧结晶,诞生10年了,几乎每个功能细节都蕴藏着无数开发者的期待和汗水; 她就是Lodop(读音“劳道谱”),没有别的名称,她是web开发的必选伴侣; 现在,她又添了个小兄弟,名叫C-Lodop(可编程的云打印),未来将由他开创......

相关链接:

JasperReports

JasperReports是一个基于Java的开源报表工具,它可以在Java环境下像其它IDE报表工具一样来制作报表。JasperReports 支持PDF、HTML、XLS、CSV和XML文件输出格式。JasperReports是当前Java开发者最常用的报表工具。

LINUX系统下PDF字体异常

doc/fonts 下的字体上传至 /usr/share/fonts

相关链接

项目结构

EasyPrint
├─ main
│  ├─ java
│  │  └─ cn
│  │   └─ nn200433
│  │    └─ print 
│  │     ├─ config
│  │     │  ├─ PrintProperties.java                                 application.yml
│  │     │  └─ PrintStarterAutoConfig.java                          初始化工具类,注入配置
│  │     ├─ constants
│  │     │  └─ PrintConstant.java                                   常量类
│  │     ├─ entity
│  │     │  ├─ HtmlRenderData.java                                  模板填充数据对象
│  │     │  ├─ HtmlRenderDataSource.java                            模板数据来源 枚举类
│  │     │  ├─ PaperStyle.java                                      纸张样式 枚举类
│  │     │  └─ PrintConfig.java                                     打印风格对象(如纸张样式,内容边距......)
│  │     ├─ Printer.java                                            lodop打印调用类(组装打印代码供前端使用)
│  │     ├─ service
│  │     │  ├─ B64ImgReplacedElementFactory.java
│  │     │  ├─ BaseRenderFactoryHandler.java
│  │     │  └─ customer                                             自定义化接口
│  │     │   ├─ impl
│  │     │   │  ├─ DefaultJasperReportDataListCoverImpl.java        dataList 的默认 JasperReportParametersCover实现
│  │     │   │  └─ DefaultJasperReportParametersMapCoverImpl.java   parametersMap 的默认 JasperReportParametersCover实现
│  │     │   └─ JasperReportParametersCover.java                    jasperReport报表参数覆盖
│  │     └─ util
│  │      ├─ HtmlRenderFactoryUtil.java                             html渲染工具类
│  │      ├─ PdfRenderFactoryUtil.java                              pdf渲染工具类
│  │      ├─ OfdRenderFactoryUtil.java                              ofd渲染工具类(《GB/T 33190-2016电子文件存储与交换格式-版式文档》)
│  │      └─ SpringContextHolder.java
│  └─ resources
│   ├─ application.yml                                              配置文件
│   ├─ print-template                                               模板文件目录
│   │  ├─ demo4.html                                                - 测试样例(beetl)
│   │  └─ Test_A4.jrxml                                             - 测试样例(JasperReport)
│   └─ static
│    ├─ lodop_install                                               打印控件下载路径
│    │  ├─ CLodop_Setup_for_Win32NT.exe
│    │  ├─ install_lodop32.exe
│    │  └─ install_lodop64.exe
│    └─ vendors
│     ├─ html2canvas                                                html转图片插件
│     │  ├─ html2canvas.js
│     │  └─ html2canvas.min.js
│     └─ lodop                                                      lodop打印插件
│      ├─ LodopFuncs.js                                             - lodop打印核心代码
│      └─ Lodop_print.js                                            - 自定义调用方法
└─ test                                                             DEMO运行示例

开发教程

引入jar包

<!-- 自行编译 -->
<dependency>
    <groupId>cn.nn200433</groupId>
    <artifactId>EasyPrint</artifactId>
    <version>${latestVersion}</version>
</dependency>

<!-- hutool工具包 -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>${hutool.version}</version>
</dependency>

<!-- JSON工具类 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>${fastjson.version}</version>
</dependency>

配置

print:
    # 传入打印组件的数据进行反转义
  dataUnescape: true
  # 模板路径,默认
  templatePath:

工具类

// ========================================= HtmlRenderFactoryUtil =========================================

/**
 * 套打模式渲染
 * 自定义数据并渲染为模板
 *
 * @param templateName    模板名称
 * @param htmlRenderData  填充数据(若dataList为空,则采用druid数据源)
 * @param subTemplateName 子模板名称(在jasperReport中,添加相同个数名称为“SUB_REPORT_[0,1,2......]”;Class属性为“net.sf.jasperreports.engine.JasperReport”的Parameters参数)
 * @return {@link String}
 */
public static List<String> renderList(String templateName, 
                                      HtmlRenderData htmlRenderData, 
                                      int pageDataSize,
									  String... subTemplateName);

/**
 * 套打模式渲染
 * 自定义数据并渲染为模板
 *
 * @param templateName        模板名称
 * @param htmlRenderData      填充数据(若dataList为空,则采用druid数据源)
 * @param pageDataSize        每页打印数据量
 * @param customerParamMapFun 自定义每页的参数映射处理
 * @param customerDataListFun 自定义每页的数据列表处理
 * @param subTemplateName     子模板名称(在jasperReport中,添加相同个数名称为“SUB_REPORT_[0,1,2......]”;Class属性为“net.sf.jasperreports.engine.JasperReport”的Parameters参数)
 * @return {@link String}
 */
public static List<String> renderList(String templateName, 
                                      HtmlRenderData htmlRenderData, 
                                      int pageDataSize,
									  JasperReportParametersCover<Map<String, Object>> customerParamMapFun,
									  JasperReportParametersCover<List<Map<String, ?>>> customerDataListFun,
									  String... subTemplateName);

/**
 * 渲染(使用默认html处理程序)
 * 自定义数据并渲染为模板
 *
 * @param templateName    模板名称
 * @param htmlRenderData  填充数据(若dataList为空,则采用druid数据源)
 * @param subTemplateName 子模板名称(在jasperReport中,添加相同个数名称为“SUB_REPORT_[0,1,2......]”;Class属性为“net.sf.jasperreports.engine.JasperReport”的Parameters参数)
 * @return {@link String}
 */
public static String render(String templateName, HtmlRenderData htmlRenderData, String... subTemplateName);

/**
 * 渲染
 * 自定义数据并渲染为模板
 *
 * @param templateName        模板名称
 * @param htmlRenderData      填充数据(若dataList为空,则采用druid数据源)
 * @param customerParamMapFun 自定义参数映射处理。不传且 print.data.unescape 打印数据反转义启用时,使用默认实现 {@link cn.hf.ext.print.service.customer.impl.DefaultJasperReportParametersMapCoverImpl}
 * @param customerDataListFun 自定义数据列表处理,不传且 print.data.unescape 打印数据反转义启用时,使用默认实现 {@link cn.hf.ext.print.service.customer.impl.DefaultJasperReportDataListCoverImpl}
 * @param subTemplateName     子模板名称(在jasperReport中,添加相同个数名称为“SUB_REPORT_[0,1,2......]”;Class属性为“net.sf.jasperreports.engine.JasperReport”的Parameters参数)
 * @return {@link String}
 */
public static String render(String templateName,
							HtmlRenderData htmlRenderData,
							JasperReportParametersCover<Map<String, Object>> customerParamMapFun,
							JasperReportParametersCover<List<Map<String, ?>>> customerDataListFun,
							String... subTemplateName);

/**
 * 使用beetl渲染
 *
 * @param templateName 模板名称
 * @param dataMap      数据
 * @return {@link String }
 * @author sjx
 * @date 2020年09月30日 16:24:01
 */
public static String render(String templateName, Map<String, Object> dataMap);
/**
 * 使用beetl渲染
 *
 * @param templateName       模板名称
 * @param dataMap            数据
 * @param customerDataMapFun 自定义数据对象处理
 * @return {@link String }
 * @author sjx
 * @date 2020年09月30日 16:24:01
 */
public static String render(String templateName, Map<String, Object> dataMap, JasperReportParametersCover<Map<String, Object>> customerDataMapFun);
							
// ========================================= PdfRenderFactoryUtil =========================================

/**
 * 渲染
 *
 * @param templateName    模板名称
 * @param htmlRenderData  填充数据(若dataList为空,则采用druid数据源)
 * @param subTemplateName 子模板名称(在jasperReport中,添加相同个数名称为“SUB_REPORT_[0,1,2......]”;Class属性为“net.sf.jasperreports.engine.JasperReport”的Parameters参数)
 * @return @return {@link File }
 */
public static File render(String templateName, HtmlRenderData htmlRenderData, String... subTemplateName);

/**
 * 渲染
 * 自定义数据并渲染为模板
 *
 * @param templateName           模板名称
 * @param htmlRenderData         填充数据(若dataList为空,则采用druid数据源)
 * @param customerParamMapStrFun 自定义数据对象转为JSON字符串后的处理
 * @param customerDataListStrFun 自定义数据对象转为JSON字符串后的处理
 * @param subTemplateName        子模板名称(在jasperReport中,添加相同个数名称为“SUB_REPORT_[0,1,2......]”;Class属性为“net.sf.jasperreports.engine.JasperReport”的Parameters参数)
 * @return @return {@link File }
 */
public static File render(String templateName,
						  HtmlRenderData htmlRenderData,
						  JasperReportParametersCover<Map<String, Object>> customerParamMapStrFun,
						  JasperReportParametersCover<List<Map<String, ?>>> customerDataListStrFun,
						  String... subTemplateName);

/**
 * 渲染
 *
 * @param templateName    模板名称
 * @param htmlRenderData  填充数据(若dataList为空,则采用druid数据源)
 * @param subTemplateName 子模板名称(在jasperReport中,添加相同个数名称为“SUB_REPORT_[0,1,2......]”;Class属性为“net.sf.jasperreports.engine.JasperReport”的Parameters参数)
 * @return @return {@link byte[] }
 */
public static byte[] render2Bytes(String templateName, HtmlRenderData htmlRenderData, String... subTemplateName);

/**
 * 渲染
 * 自定义数据并渲染为模板
 *
 * @param templateName           模板名称
 * @param htmlRenderData         填充数据(若dataList为空,则采用druid数据源)
 * @param customerParamMapStrFun 自定义数据对象转为JSON字符串后的处理
 * @param customerDataListStrFun 自定义数据对象转为JSON字符串后的处理
 * @param subTemplateName        子模板名称(在jasperReport中,添加相同个数名称为“SUB_REPORT_[0,1,2......]”;Class属性为“net.sf.jasperreports.engine.JasperReport”的Parameters参数)
 * @return @return {@link byte[] }
 */
public static byte[] render2Bytes(String templateName,
								  HtmlRenderData htmlRenderData,
								  JasperReportParametersCover<Map<String, Object>> customerParamMapStrFun,
								  JasperReportParametersCover<List<Map<String, ?>>> customerDataListStrFun,
								  String... subTemplateName);

/**
 * html转pdf
 *
 * <pre>
 * 注:默认只处理宋体
 * 页面中字体不能使用中文,需要使用英文名称,而且是大小写敏感的!例如宋体的英文名称是 SimSun(注意不是simsun!,首字母都是大写的)
 * 错误写法:font-family:宋体 或者  font-family:simsun
 * 正确写法:font-family:SimSun 或者 font-family:SimHei
 * </pre>
 *
 * @param htmlString html字符串
 * @return @return {@link File }
 */
public static File htmlToPdf(String htmlString);

/**
 * html转pdf
 *
 * <pre>
 * 注:默认只处理宋体
 * 页面中字体不能使用中文,需要使用英文名称,而且是大小写敏感的!例如宋体的英文名称是 SimSun(注意不是simsun!,首字母都是大写的)
 * 错误写法:font-family:宋体 或者  font-family:simsun
 * 正确写法:font-family:SimSun 或者 font-family:SimHei
 * </pre>
 *
 * @param htmlString           html字符串
 * @param isInsideGenerateHtml 是否内部生成的Html,HtmlRenderFactoryUtil产生的html为内部生成(做过特殊处理)
 * @return @return {@link File }
 */
public static File htmlToPdf(String htmlString, Boolean isInsideGenerateHtml);

/**
 * html转pdf
 *
 * <pre>
 * 注:默认只处理宋体
 * 页面中字体不能使用中文,需要使用英文名称,而且是大小写敏感的!例如宋体的英文名称是 SimSun(注意不是simsun!,首字母都是大写的)
 * 错误写法:font-family:宋体 或者  font-family:simsun
 * 正确写法:font-family:SimSun 或者 font-family:SimHei
 * </pre>
 *
 * @param htmlString html字符串
 * @return @return {@link File }
 */
public static byte[] htmlToPdfBytes(String htmlString);

/**
 * html转pdf
 *
 * <pre>
 * 注:默认只处理宋体
 * 页面中字体不能使用中文,需要使用英文名称,而且是大小写敏感的!例如宋体的英文名称是 SimSun(注意不是simsun!,首字母都是大写的)
 * 错误写法:font-family:宋体 或者  font-family:simsun
 * 正确写法:font-family:SimSun 或者 font-family:SimHei
 * </pre>
 *
 * @param htmlString           html字符串
 * @param isInsideGenerateHtml 是否内部生成的Html,HtmlRenderFactoryUtil产生的html为内部生成(做过特殊处理)
 * @return @return {@link byte[] }
 */
public static byte[] htmlToPdfBytes(String htmlString, Boolean isInsideGenerateHtml);

// ========================================= OfdRenderFactoryUtil =========================================

/**
 * 渲染(内部发pdf转ofd)
 *
 * @param templateName    模板名称
 * @param htmlRenderData  填充数据(若dataList为空,则采用druid数据源)
 * @param subTemplateName 子模板名称(在jasperReport中,添加相同个数名称为“SUB_REPORT_[0,1,2......]”;Class属性为“net.sf.jasperreports.engine.JasperReport”的Parameters参数)
 * @return @return {@link File }
 */
public static File render(String templateName, HtmlRenderData htmlRenderData, String... subTemplateName);

/**
 * 渲染(内部发pdf转ofd)
 * 自定义数据并渲染为模板
 *
 * @param templateName           模板名称
 * @param htmlRenderData         填充数据(若dataList为空,则采用druid数据源)
 * @param customerParamMapStrFun 自定义数据对象转为JSON字符串后的处理
 * @param customerDataListStrFun 自定义数据对象转为JSON字符串后的处理
 * @param subTemplateName        子模板名称(在jasperReport中,添加相同个数名称为“SUB_REPORT_[0,1,2......]”;Class属性为“net.sf.jasperreports.engine.JasperReport”的Parameters参数)
 * @return @return {@link File }
 */
public static File render(String templateName,
						  HtmlRenderData htmlRenderData,
						  JasperReportParametersCover<Map<String, Object>> customerParamMapStrFun,
						  JasperReportParametersCover<List<Map<String, ?>>> customerDataListStrFun,
						  String... subTemplateName);

/**
 * 渲染(内部发pdf转ofd)
 *
 * @param templateName    模板名称
 * @param htmlRenderData  填充数据(若dataList为空,则采用druid数据源)
 * @param subTemplateName 子模板名称(在jasperReport中,添加相同个数名称为“SUB_REPORT_[0,1,2......]”;Class属性为“net.sf.jasperreports.engine.JasperReport”的Parameters参数)
 * @return @return {@link byte[] }
 */
public static byte[] render2Bytes(String templateName, HtmlRenderData htmlRenderData, String... subTemplateName);

/**
 * 渲染(内部发pdf转ofd)
 * 自定义数据并渲染为模板
 *
 * @param templateName           模板名称
 * @param htmlRenderData         填充数据(若dataList为空,则采用druid数据源)
 * @param customerParamMapStrFun 自定义数据对象转为JSON字符串后的处理
 * @param customerDataListStrFun 自定义数据对象转为JSON字符串后的处理
 * @param subTemplateName        子模板名称(在jasperReport中,添加相同个数名称为“SUB_REPORT_[0,1,2......]”;Class属性为“net.sf.jasperreports.engine.JasperReport”的Parameters参数)
 * @return @return {@link byte[] }
 */
public static byte[] render2Bytes(String templateName,
								  HtmlRenderData htmlRenderData,
								  JasperReportParametersCover<Map<String, Object>> customerParamMapStrFun,
								  JasperReportParametersCover<List<Map<String, ?>>> customerDataListStrFun,
								  String... subTemplateName);

/**
 * html转ofd(内部生成html转换为pdf文件,最后再转为ofd文件)
 *
 * <pre>
 * 注:默认只处理宋体
 * 页面中字体不能使用中文,需要使用英文名称,而且是大小写敏感的!例如宋体的英文名称是 SimSun(注意不是simsun!,首字母都是大写的)
 * 错误写法:font-family:宋体 或者  font-family:simsun
 * 正确写法:font-family:SimSun 或者 font-family:SimHei
 * </pre>
 *
 * @param htmlString html字符串
 * @return @return {@link File }
 */
public static File htmlToOfd(String htmlString);

/**
 * html转ofd(内部生成html转换为pdf文件,最后再转为ofd文件)
 *
 * <pre>
 * 注:默认只处理宋体
 * 页面中字体不能使用中文,需要使用英文名称,而且是大小写敏感的!例如宋体的英文名称是 SimSun(注意不是simsun!,首字母都是大写的)
 * 错误写法:font-family:宋体 或者  font-family:simsun
 * 正确写法:font-family:SimSun 或者 font-family:SimHei
 * </pre>
 *
 * @param htmlString           html字符串
 * @param isInsideGenerateHtml 是否内部生成的Html,HtmlRenderFactoryUtil产生的html为内部生成(做过特殊处理)
 * @return @return {@link File }
 */
public static File htmlToOfd(String htmlString, Boolean isInsideGenerateHtml);

/**
 * html转ofd(内部生成html转换为pdf文件,最后再转为ofd文件)
 *
 * <pre>
 * 注:默认只处理宋体
 * 页面中字体不能使用中文,需要使用英文名称,而且是大小写敏感的!例如宋体的英文名称是 SimSun(注意不是simsun!,首字母都是大写的)
 * 错误写法:font-family:宋体 或者  font-family:simsun
 * 正确写法:font-family:SimSun 或者 font-family:SimHei
 * </pre>
 *
 * @param htmlString           html字符串
 * @param isInsideGenerateHtml 是否内部生成的Html,HtmlRenderFactoryUtil产生的html为内部生成(做过特殊处理)
 * @return @return {@link byte[] }
 */
public static byte[] htmlToOfdBytes(String htmlString, Boolean isInsideGenerateHtml);

/**
 * html转ofd(内部生成html转换为pdf文件,最后再转为ofd文件)
 *
 * <pre>
 * 注:默认只处理宋体
 * 页面中字体不能使用中文,需要使用英文名称,而且是大小写敏感的!例如宋体的英文名称是 SimSun(注意不是simsun!,首字母都是大写的)
 * 错误写法:font-family:宋体 或者  font-family:simsun
 * 正确写法:font-family:SimSun 或者 font-family:SimHei
 * </pre>
 *
 * @param htmlString html字符串
 * @return @return {@link File }
 */
public static byte[] htmlToOfdBytes(String htmlString);

安装软件

注:JaspersoftStudio使用教程请参考根目录doc文件夹下的pdf文档。iReport是JaspersoftStudio的前身,用法几乎一致。

JasperReport模板

resource下新建print-template打印模板存放目录。

模板文件如下:

Test_A4.jrxml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.12.2.final using JasperReports Library version 6.12.2-75c5e90a222ab406e416cbf590a5397028a52de3  -->
<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="Test_A4" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="262435ae-66a3-4509-ac68-e163b333f6d3">
	<property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
	<parameter name="TABLE_TITLE" class="java.lang.String">
		<parameterDescription><![CDATA[标题]]></parameterDescription>
	</parameter>
	<queryString>
		<![CDATA[]]>
	</queryString>
	<field name="FIELD_ACCOUNT" class="java.lang.String">
		<fieldDescription><![CDATA[帐号]]></fieldDescription>
	</field>
	<field name="FIELD_REAL_NAME" class="java.lang.String">
		<fieldDescription><![CDATA[真实姓名]]></fieldDescription>
	</field>
	<background>
		<band splitType="Prevent"/>
	</background>
	<title>
		<band height="60" splitType="Stretch">
			<textField>
				<reportElement x="180" y="0" width="200" height="40" uuid="d07e7265-85f8-4e43-8050-5573734fd1e9"/>
				<textElement textAlignment="Center" verticalAlignment="Middle">
					<font fontName="宋体" size="21"/>
				</textElement>
				<textFieldExpression><![CDATA[$P{TABLE_TITLE}]]></textFieldExpression>
			</textField>
		</band>
	</title>
	<columnHeader>
		<band height="30" splitType="Stretch">
			<staticText>
				<reportElement x="0" y="0" width="280" height="30" uuid="67e869d1-74ec-4668-8e98-ab9987a37dae"/>
				<box>
					<topPen lineWidth="1.0"/>
					<leftPen lineWidth="1.0"/>
					<bottomPen lineWidth="1.0"/>
					<rightPen lineWidth="1.0"/>
				</box>
				<textElement textAlignment="Center" verticalAlignment="Middle">
					<font fontName="宋体" size="18" isBold="true"/>
				</textElement>
				<text><![CDATA[帐号]]></text>
			</staticText>
			<staticText>
				<reportElement x="280" y="0" width="275" height="30" uuid="431d78fe-1515-483a-8bd3-6ad5fd8ae4c5"/>
				<box>
					<topPen lineWidth="1.0"/>
					<leftPen lineWidth="1.0"/>
					<bottomPen lineWidth="1.0"/>
					<rightPen lineWidth="1.0"/>
				</box>
				<textElement textAlignment="Center" verticalAlignment="Middle">
					<font fontName="宋体" size="18" isBold="true"/>
				</textElement>
				<text><![CDATA[真实姓名]]></text>
			</staticText>
		</band>
	</columnHeader>
	<detail>
		<band height="30" splitType="Stretch">
			<textField>
				<reportElement x="0" y="0" width="280" height="30" uuid="63eb86bb-3eb1-43d4-93df-4f70f23f4446"/>
				<box>
					<topPen lineWidth="1.0"/>
					<leftPen lineWidth="1.0"/>
					<bottomPen lineWidth="1.0"/>
					<rightPen lineWidth="1.0"/>
				</box>
				<textElement textAlignment="Center" verticalAlignment="Middle">
					<font fontName="宋体" size="18"/>
				</textElement>
				<textFieldExpression><![CDATA[$F{FIELD_ACCOUNT}]]></textFieldExpression>
			</textField>
			<textField>
				<reportElement x="280" y="0" width="275" height="30" uuid="4dae300a-668c-4f21-91a9-bc8c0d692477"/>
				<box>
					<topPen lineWidth="1.0"/>
					<leftPen lineWidth="1.0"/>
					<bottomPen lineWidth="1.0"/>
					<rightPen lineWidth="1.0"/>
				</box>
				<textElement textAlignment="Center" verticalAlignment="Middle">
					<font fontName="宋体" size="18"/>
				</textElement>
				<textFieldExpression><![CDATA[$F{FIELD_REAL_NAME}]]></textFieldExpression>
			</textField>
		</band>
	</detail>
</jasperReport>

注:

1. 主表中每增加一个子表需要在Parameters下新增一个SUB_REPORT_[0,1,2.....]net.sf.jasperreports.engine.JasperReport对象参数。

2. 子表的数据可以定义在Parameters下,参数类型为MapList

后端代码

关键代码:

// 模板渲染
String html = HtmlRenderFactoryUtil.render("Test_A4",
        new HtmlRenderData(paramMaps, detailList));

System.out.println("==================== JasperReport模板渲染后的Html代码 ====================");
System.out.println(html);

// 打印参数配置
PrintConfig printConfig = new PrintConfig(html);

// 生成打印控件需要的代码
String str = new Printer(printConfig).print();

System.out.println("==================== Lodop打印javascript脚本语句 ====================");
System.out.println(str);

举个web调用例子:

/**
 * 打印
 *
 * @param id id 记录ID
 * @return {@link String}
 */
@PostMapping("{id}/print")
public Response print(@PathVariable("id") String id) {
    Response response = null;
    try {
        // 获取待渲染的数据
        Map<String,Object> dataMap = printData(id);
        // 生成html表格
        String html = HtmlRenderFactoryUtil.render("hospitality",
                new HtmlRenderData(
                    MapUtil.get(dataMap, "entertainmentExpensesMap", new TypeReference<Map<String, Object>>() {}),
                    HtmlRenderDataSource.DATA_FROM_COLLECTION_MAP
                )
        );
        
        // 打印配置,如横向/纵向
        // 不设置纸张样式时,默认是 A4 但 长宽全是 0
        PrintConfig printConfig = new PrintConfig(html);

        response = Response.ok();        
        // new Printer(printConfig).print() 该语句将生成调用Lodop控件的脚本
        response.put("expression", new Printer(printConfig).print());
    } catch (Exception e) {
        logger.error("======> 打印出错", e);
        response = Response.error(e.getMessage());
    }

    return response;
}

详细方法用例:

package cn.nn200433.print;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.lang.Console;
import Printer;
import HtmlRenderData;
import PrintConfig;
import JasperReportParametersCover;
import HtmlRenderFactoryUtil;
import PdfRenderFactoryUtil;
import com.forte.util.utils.MockUtil;
import org.junit.Test;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 打印测试
 *
 * @author sjx
 * @date 2020年05月18日 0018 15:05:05
 */
public class PrintTest {

    /**
     * 示例1 - jasperReport导出html使用示例
     *
     * @throws Exception 异常
     */
    @Test
    public void demo1() throws Exception {
        TimeInterval timer = DateUtil.timer();

        Map<String, Object> paramMaps = new HashMap<String, Object>(1);
        paramMaps.put("TABLE_TITLE", "测试标题");

        List<Map<String, ?>> detailList = new ArrayList<Map<String, ?>>(20);
        for (int i = 0; i < 20; i++) {
            Map<String, Object> tempMap = new HashMap<String, Object>();
            tempMap.put("FIELD_ACCOUNT", MockUtil.title(5));
            tempMap.put("FIELD_REAL_NAME", MockUtil.cname());
            detailList.add(tempMap);
        }

        // 模板渲染
        String html = HtmlRenderFactoryUtil.render("Test_A4",
                new HtmlRenderData(paramMaps, detailList), new JasperReportParametersCover<Map<String, Object>>() {
                    @Override
                    public Map<String, Object> cover(Map<String, Object> parameterMap) throws Exception {
                        return parameterMap;
                    }
                }, new JasperReportParametersCover<List<Map<String, ?>>>() {
                    @Override
                    public List<Map<String, ?>> cover(List<Map<String, ?>> dataList) throws Exception {
                        return dataList;
                    }
                });

        System.out.println("==================== JasperReport模板渲染后的Html代码 ====================");
        System.out.println(html);

        // 打印参数配置
        PrintConfig printConfig = new PrintConfig(html);

        // 生成打印控件需要的代码
        String str = new Printer(printConfig).print();

        System.out.println("==================== Lodop打印javascript脚本语句 ====================");
        System.out.println(str);

        System.out.println("打印运行耗时 " + timer.intervalSecond() + " 秒");
    }

    /**
     * 示例2 - jasperReport导出pdf示例
     *
     * @return
     */
    @Test
    public void demo2() {
        TimeInterval timer = DateUtil.timer();

        Map<String, Object> paramMaps = new HashMap<String, Object>(1);
        paramMaps.put("TABLE_TITLE", "测试&bull;标题");

        List<Map<String, ?>> detailList = new ArrayList<Map<String, ?>>(20);
        for (int i = 0; i < 20; i++) {
            Map<String, Object> tempMap = new HashMap<String, Object>();
            tempMap.put("FIELD_ACCOUNT", MockUtil.title(5) + "&gt;");
            tempMap.put("FIELD_REAL_NAME", MockUtil.cname());
            detailList.add(tempMap);
        }

        // 模板渲染
        File pdfFile = PdfRenderFactoryUtil.render("Test_A4",
                new HtmlRenderData(paramMaps, detailList));

        Console.log("======> 文件路径 = {}", pdfFile.getAbsolutePath());

        System.out.println("打印运行耗时 " + timer.intervalSecond() + " 秒");
    }

    /**
     * 示例3 - html转pdf
     *
     * @return
     */
    @Test
    public void demo3() {
        // 字体只处理宋体!!!!

        String s = "<!DOCTYPE html PUBLIC\"-//W3C//DTD XHTML 1.0 Transitional//EN\"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html><head><title></title><meta http-equiv=\"Content-Type\"content=\"text/html; charset=UTF-8\"/><style type=\"text/css\">a{text-decoration:none}</style></head><body text=\"#000000\"link=\"#000000\"alink=\"#000000\"vlink=\"#000000\"><table width=\"100%\"cellpadding=\"0\"cellspacing=\"0\"border=\"0\"><tr><td width=\"50%\">&nbsp;</td><td align=\"center\"><a name=\"JR_PAGE_ANCHOR_0_1\"></a><table class=\"jrPage\"cellpadding=\"0\"cellspacing=\"0\"border=\"0\"style=\"empty-cells: show; width: 595px; border-collapse: collapse; background-color: white;\"><tr valign=\"top\"style=\"height:0\"><td style=\"width:20px\"></td><td style=\"width:180px\"></td><td style=\"width:100px\"></td><td style=\"width:100px\"></td><td style=\"width:175px\"></td><td style=\"width:20px\"></td></tr><tr valign=\"top\"style=\"height:20px\"><td colspan=\"6\"></td></tr><tr valign=\"top\"style=\"height:40px\"><td colspan=\"2\"></td><td colspan=\"2\"style=\"text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 21px; line-height: 1.140625;\">测试标题</span></td><td colspan=\"2\"></td></tr><tr valign=\"top\"style=\"height:20px\"><td colspan=\"6\"></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625; font-weight: bold;\">帐号</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625; font-weight: bold;\">真实姓名</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Vtvjo</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">席皂斋</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Ltoix</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">连雪空</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Jazsj</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">屈速</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Tzans</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">谷梁成</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Eqakb</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">寿呈</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Izgmw</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">萧菜铣</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Vizmk</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">隆噶</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Nhbkv</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">宦譬</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Hhpzy</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">郇欠放</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Xyupx</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">蔺换稍</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Usczd</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">祖玩该</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Wkfkc</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">韶芥写</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Qgrvq</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">綦毋恋</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Dmkmb</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">鲁驯</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Yzlsc</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">籍仿</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Nfwkd</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">都筒</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Nsegj</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">莘喇距</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Mvnln</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">覃知</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Tkbkb</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">谈酸</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">Zynak</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: 宋体; color: #000000; font-size: 18px; line-height: 1.140625;\">边捷</span></td><td></td></tr><tr valign=\"top\"style=\"height:132px\"><td colspan=\"6\"></td></tr></table></td><td width=\"50%\">&nbsp;</td></tr></table></body></html>";
        File file = PdfRenderFactoryUtil.htmlToPdf(s, Boolean.FALSE);
        Console.log("======> 文件路径1 = {}", file.getAbsolutePath());
        // 该 html 的 style中的 font-family: \'宋体\' 经过特殊处理,需注意
        String s1 = "<!DOCTYPE html PUBLIC\"-//W3C//DTD XHTML 1.0 Transitional//EN\"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html><head><title></title><meta http-equiv=\"Content-Type\"content=\"text/html; charset=UTF-8\"/><style type=\"text/css\">a{text-decoration:none}</style></head><body text=\"#000000\"link=\"#000000\"alink=\"#000000\"vlink=\"#000000\"><table width=\"100%\"cellpadding=\"0\"cellspacing=\"0\"border=\"0\"><tr><td width=\"50%\">&nbsp;</td><td align=\"center\"><a name=\"JR_PAGE_ANCHOR_0_1\"></a><table class=\"jrPage\"cellpadding=\"0\"cellspacing=\"0\"border=\"0\"style=\"empty-cells: show; width: 595px; border-collapse: collapse; background-color: white;\"><tr valign=\"top\"style=\"height:0\"><td style=\"width:20px\"></td><td style=\"width:180px\"></td><td style=\"width:100px\"></td><td style=\"width:100px\"></td><td style=\"width:175px\"></td><td style=\"width:20px\"></td></tr><tr valign=\"top\"style=\"height:20px\"><td colspan=\"6\"></td></tr><tr valign=\"top\"style=\"height:40px\"><td colspan=\"2\"></td><td colspan=\"2\"style=\"text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 21px; line-height: 1.140625;\">测试标题</span></td><td colspan=\"2\"></td></tr><tr valign=\"top\"style=\"height:20px\"><td colspan=\"6\"></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625; font-weight: bold;\">帐号</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625; font-weight: bold;\">真实姓名</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Vtvjo</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">席皂斋</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Ltoix</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">连雪空</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Jazsj</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">屈速</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Tzans</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">谷梁成</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Eqakb</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">寿呈</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Izgmw</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">萧菜铣</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Vizmk</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">隆噶</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Nhbkv</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">宦譬</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Hhpzy</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">郇欠放</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Xyupx</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">蔺换稍</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Usczd</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">祖玩该</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Wkfkc</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">韶芥写</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Qgrvq</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">綦毋恋</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Dmkmb</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">鲁驯</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Yzlsc</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">籍仿</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Nfwkd</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">都筒</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Nsegj</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">莘喇距</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Mvnln</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: '\\'宋体\\''; color: #000000; font-size: 18px; line-height: 1.140625;\">覃知</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Tkbkb</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">谈酸</span></td><td></td></tr><tr valign=\"top\"style=\"height:30px\"><td></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">Zynak</span></td><td colspan=\"2\"style=\"border: 1px solid #000000; text-indent: 0px;  vertical-align: middle;text-align: center;\"><span style=\"font-family: \\'宋体\\'; color: #000000; font-size: 18px; line-height: 1.140625;\">边捷</span></td><td></td></tr><tr valign=\"top\"style=\"height:132px\"><td colspan=\"6\"></td></tr></table></td><td width=\"50%\">&nbsp;</td></tr></table></body></html>";
        File file1 = PdfRenderFactoryUtil.htmlToPdf(s1);
        Console.log("======> 文件路径2 = {}", file1.getAbsolutePath());
    }

    /**
     * 示例4 - 使用beetl模板引擎
     *
     * @throws Exception 异常
     */
    @Test
    public void demo4() throws Exception {
        TimeInterval timer = DateUtil.timer();

        Map<String, Object> paramMaps = new HashMap<String, Object>(1);
        paramMaps.put("title", "测试标题");
        paramMaps.put("date", "2020-01-01 至 2020-02-28");

        List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>(3);
        for (int i = 0; i < 5; i++) {
            HashMap<String, Object> stringObjectHashMap = new HashMap<>();
            stringObjectHashMap.put("orgPosition", "测试" + i);
            stringObjectHashMap.put("opinion", "测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试");
            stringObjectHashMap.put("createByName", "姓名_" + i);
            stringObjectHashMap.put("createDateStr", "2020-09-30");
            dataList.add(stringObjectHashMap);
        }
        paramMaps.put("dataList", dataList);
        // 模板渲染
        String html = HtmlRenderFactoryUtil.render("demo4.html", paramMaps);

        System.out.println("==================== beetl模板渲染后的Html代码 ====================");
        System.out.println(html);

        // 打印参数配置
        PrintConfig printConfig = new PrintConfig(html);

        // 生成打印控件需要的代码
        String str = new Printer(printConfig).print();

        System.out.println("==================== Lodop打印javascript脚本语句 ====================");
        System.out.println(str);

        System.out.println("打印运行耗时 " + timer.intervalSecond() + " 秒");
    }

    /**
     * 示例5 - 套打
     *
     * @throws Exception 异常
     */
    @Test
    public void demo5() throws Exception {
        TimeInterval timer = DateUtil.timer();

        Map<String, Object> paramMaps = new HashMap<String, Object>(1);
        paramMaps.put("TABLE_TITLE", "测试标题");

        List<Map<String, ?>> detailList = new ArrayList<Map<String, ?>>(20);
        for (int i = 0; i < 5; i++) {
            Map<String, Object> tempMap = new HashMap<String, Object>();
            tempMap.put("FIELD_ACCOUNT", MockUtil.title(5));
            tempMap.put("FIELD_REAL_NAME", MockUtil.cname());
            detailList.add(tempMap);
        }

        // 模板渲染
        List<String> htmlList = HtmlRenderFactoryUtil.renderList("Test_A4",
                new HtmlRenderData(paramMaps, detailList), 4,
                new JasperReportParametersCover<Map<String, Object>>() {
                    @Override
                    public Map<String, Object> cover(Map<String, Object> paramMap) throws Exception {
                        paramMap.put("TABLE_TITLE", "测试标题2");
                        Console.log("======> {}", paramMap);
                        return paramMap;
                    }
                }, null);
        System.out.println("==================== JasperReport模板渲染后的Html代码 ====================");
        Console.log(htmlList);

        // 打印参数配置
        PrintConfig printConfig = new PrintConfig(htmlList);

        System.out.println("==================== Lodop打印javascript脚本语句 ====================");
        // 生成打印控件需要的代码
        String str = new Printer(printConfig).printList();
        System.out.println(str);

        System.out.println("打印运行耗时 " + timer.intervalSecond() + " 秒");
    }

}

前端代码

引入javascript插件:

<!-- html转canvas图片 -->
<script src="${staticPath}/vendors/html2canvas/html2canvas.min.js"></script>
<!-- 引入打印控件 -->
<script src="${staticPath}/vendors/lodop/LodopFuncs.js"></script>
<object  id="LODOP_OB" classid="clsid:2105C259-1E0C-4534-8141-A753534CB4CA" width=0 height=0>
       <embed id="LODOP_EM" type="application/x-print-lodop" width=0 height=0></embed>
</object>
<script src="${staticPath}/vendors/lodop/Lodop_print.js"></script>

调用方法:

// html超文本内容打印
let htmlContent = $(layero).find('iframe').eq(0).contents().find('#detail').html();
printPreviewHtml(htmlContent);


// 图片打印
html2canvas($(layero).find('iframe').eq(0).contents().find('#detail').get(0)).then(canvas => {
	// 截图质量(0-1)
	printPreviewImg(canvas.toDataURL("image/png", 1), '5mm', 5, '99%', '50%');
});


// 模板渲染打印
printPreview("${adminPath}/oa/travelReimbursement/" + rowId + "/print", top.layer);

提供调用的javascript脚本:

/**
 * 打印预览,用于后台返回数据打印
 *
 * @param ajaxUrl         ajax请求地址
 * @param layerAlert      layer弹窗组件对象
 */
function printPreview(ajaxUrl, layerAlert) {
    try {
        // 检查是否安装lodop
        checkIsInstall();

        let loadIndex;
        $.ajax({
            type: "POST",
            url: ajaxUrl,
            dataType: "json",
            beforeSend: function() {
                // 开启遮罩
                loadIndex = layerAlert.msg('打印模板渲染中...', {
                    icon: 16,
                    shade: 0.6,
                    time: 120000
                });
            },
            success: function(data) {
                // 关闭遮罩
                layerAlert.close(loadIndex);

                if (data.code == 500) {
                    layerAlert.alert("打印异常:" + data.msg, {icon: 2});
                    return;
                }

                // 打印
                eval(data.expression);
                LODOP.PREVIEW();
            }
        });
    } catch (e) {
        console.log(e);
    }
}

/**
 * 打印预览,用于网页内容打印
 *
 * @param htmlContent 超文本标记内容
 */
function printPreviewHtml(htmlContent) {
    try {
        checkIsInstall();
        LODOP.PRINT_INIT("网页内容打印");
        LODOP.ADD_PRINT_HTM(0, 0, "100%", "100%", htmlContent);
        LODOP.PREVIEW();
    } catch (e) {
        console.log(e);
    }
}

/**
 * 打印预览,用于图片打印
 *
 * @param base64ImgStr  图片的base64码
 * @param pageTop       上边距
 * @param pageLeft      左边距 34px(1px=1/96英寸)
 * @param imgWidth      图片宽度(默认百分百),支持数值跟百分比
 * @param imgHeight     图片高度(默认百分百),支持数值跟百分比
 * @param zooming       1:(可变形)扩展缩放模式;2:按原图比例(不变形)缩放模式;
 */
function printPreviewImg(base64ImgStr, pageTop = '5mm', pageLeft = 34, imgWidth = '100%',
                         imgHeight = '100%', zooming = 2) {
    try {
        checkIsInstall();
        LODOP.PRINT_INIT("图片打印");
        LODOP.ADD_PRINT_IMAGE(pageTop, pageLeft, imgWidth, imgHeight, base64ImgStr);
        // 按原图比例(不变形)缩放模式
        LODOP.SET_PRINT_STYLEA(0, 'Stretch', zooming);
        LODOP.PREVIEW();
    } catch (e) {
        console.log(e);
    }
}

test代码执行结果

运行示例

木兰宽松许可证, 第2版 木兰宽松许可证, 第2版 2020年1月 http://license.coscl.org.cn/MulanPSL2 您对"软件"的复制、使用、修改及分发受木兰宽松许可证,第2版("本许可证")的如下条款的约束: 0. 定义 "软件" 是指由"贡献"构成的许可在"本许可证"下的程序和相关文档的集合。 "贡献" 是指由任一"贡献者"许可在"本许可证"下的受版权法保护的作品。 "贡献者" 是指将受版权法保护的作品许可在"本许可证"下的自然人或"法人实体"。 "法人实体" 是指提交贡献的机构及其"关联实体"。 "关联实体" 是指,对"本许可证"下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 1. 授予版权许可 每个"贡献者"根据"本许可证"授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其"贡献",不论修改与否。 2. 授予专利许可 每个"贡献者"根据"本许可证"授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其"贡献"或以其他方式转移其"贡献"。前述专利许可仅限于"贡献者"现在或将来拥有或控制的其"贡献"本身或其"贡献"与许可"贡献"时的"软件"结合而将必然会侵犯的专利权利要求,不包括对"贡献"的修改或包含"贡献"的其他结合。如果您或您的"关联实体"直接或间接地,就"软件"或其中的"贡献"对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则"本许可证"授予您对"软件"的专利许可自您提起诉讼或发起维权行动之日终止。 3. 无商标许可 "本许可证"不提供对"贡献者"的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。 4. 分发限制 您可以在任何媒介中将"软件"以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供"本许可证"的副本,并保留"软件"中的版权、商标、专利及免责声明。 5. 免责声明与责任限制 "软件"及其中的"贡献"在提供时不带任何明示或默示的担保。在任何情况下,"贡献者"或版权所有者不对任何人因使用"软件"或其中的"贡献"而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。 6. 语言 "本许可证"以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。 条款结束 如何将木兰宽松许可证,第2版,应用到您的软件 如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: 1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; 2, 请您在软件包的一级目录下创建以"LICENSE"为名的文件,将整个许可证文本放入该文件中; 3, 请将如下声明文本放入每个源文件的头部注释中。 Copyright (c) [Year] [name of copyright holder] [Software Name] is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2 THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. Mulan Permissive Software License,Version 2 Mulan Permissive Software License,Version 2 (Mulan PSL v2) January 2020 http://license.coscl.org.cn/MulanPSL2 Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions: 0. Definition Software means the program and related documents which are licensed under this License and comprise all Contribution(s). Contribution means the copyrightable work licensed by a particular Contributor under this License. Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License. Legal Entity means the entity making a Contribution and all its Affiliates. Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, 'control' means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity. 1. Grant of Copyright License Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not. 2. Grant of Patent License Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken. 3. No Trademark License No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in section 4. 4. Distribution Restriction You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software. 5. Disclaimer of Warranty and Limitation of Liability THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT'S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 6. Language THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL. END OF THE TERMS AND CONDITIONS How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps: i. Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner; ii. Create a file named "LICENSE" which contains the whole context of this License in the first directory of your software package; iii. Attach the statement to the appropriate annotated syntax at the beginning of each source file. Copyright (c) [Year] [name of copyright holder] [Software Name] is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2 THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details.

简介

Lodop + JasperReports 打印工具类 展开 收起
Java
MulanPSL-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/diycp2015/easy-print.git
git@gitee.com:diycp2015/easy-print.git
diycp2015
easy-print
EasyPrint
master

搜索帮助