封装独立的打印工具类

This commit is contained in:
tangw 2025-07-25 17:27:37 +08:00
parent 5f80b04fdf
commit cc306258c7
7 changed files with 359 additions and 109 deletions

View File

@ -0,0 +1,334 @@
package com.czlis.interfaceCommon.utils;
import lombok.extern.slf4j.Slf4j;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRPrintServiceExporter;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.util.JRSaver;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
import net.sf.jasperreports.export.SimplePrintServiceExporterConfiguration;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.jasperreports.engine.JasperPrint;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.OrientationRequested;
/**
* JasperReports 打印/导出工具类
*/
@Component
@Slf4j
public class JasperReportUtil {
private static String template="template";
private static String templatep="template/";
/**
* 核心打印/导出方法
* @param printerName 打印机名称(可为null,null时使用默认打印机)
* @param templateName 模板名称(支持jrxml或jasper,放在resources/template目录下)
* @param parameters 非循环字段集合(报表参数,如标题、日期等)
* @param dataList 循环体数据(List集合,每条数据对应detail区域一行)
* @param pdfType 打印方式(pdfType为true导出PDF)
* @param exportPath PDF导出路径(pdfType为PDF时必传)
* @param printtimes 打印次数(可为null,默认1次)
* @param papersize 纸张尺寸(可为null,默认使用模板纸张)
* @param Orientation 纸张方向(false直打,true横打)
* @param showDialog 打印前是否预览(false直接打印,true预览)
* @throws Exception Jasper相关异常
*/
public static void printbase(
String printerName,
String templateName,
Map<String, Object> parameters,
List<?> dataList,
boolean pdfType,
String exportPath,
Integer printtimes,
String papersize,
boolean Orientation,
boolean showDialog
) throws Exception {
// 1. 校验入参
// validateParams(printType, exportPath, dataList);
// 2. 加载并编译模板(支持jrxml和jasper)
JasperReport jasperReport;
try {
jasperReport = loadTemplate(templateName);
} catch (Exception e) {
log.error("打印模板创建错误:{}",e);
throw new RuntimeException(e);
}
// 3. 处理循环数据(转换为Jasper数据源)
JRDataSource dataSource;
if (dataList == null || dataList.isEmpty()) {
dataSource=new JREmptyDataSource();
}else {
dataSource = new JRBeanCollectionDataSource(dataList);
}
// 4. 填充报表(参数+循环数据)
Map<String, Object> safeParams = parameters != null ? parameters : new HashMap<>();
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, safeParams, dataSource);
// 5. 根据打印方式执行操作
if (pdfType==false) {
// 5.1 直接打印到指定打印机
printToPrinter(jasperPrint, printerName,printtimes,papersize,Orientation,showDialog);
} else{
// 5.2 导出为PDF
exportToPdf(jasperPrint, exportPath);
}
}
/**
* 加载并编译模板(优先加载jasper,不存在则编译jrxml)
*/
private static JasperReport loadTemplate(String templateName) throws Exception {
// 模板路径:resources/templates/
String templatePath = templatep + templateName;
InputStream jasperStream = JasperReportUtil.class.getClassLoader().getResourceAsStream(templatePath + ".jasper");
if (jasperStream != null) {
// 存在已编译的jasper文件,直接加载
return (JasperReport) JRLoader.loadObject(jasperStream);
} else {
// 不存在jasper,编译jrxml
compileAndSave(templateName);
InputStream jrxmlStream = JasperReportUtil.class.getClassLoader().getResourceAsStream(templatePath + ".jrxml");
if (jrxmlStream == null) {
throw new JRException("模板不存在:" + templatePath + ".jrxml/.jasper");
}
return JasperCompileManager.compileReport(jrxmlStream);
}
}
/**
* 直接打印到指定打印机
*/
private static void printToPrinter(JasperPrint jasperPrint, String printerName,Integer printtimes,String papersize,boolean Orientation,boolean showDialog) throws JRException {
// 查找目标打印机
PrintService printService = findPrintService(printerName);
if (printService == null) {
throw new JRException("未找到指定打印机:" + (printerName == null ? "默认打印机" : printerName));
}
// 配置打印参数(跳过打印对话框,直接打印)
JRPrintServiceExporter exporter = new JRPrintServiceExporter();
SimplePrintServiceExporterConfiguration config = new SimplePrintServiceExporterConfiguration();
config.setPrintService(printService); // 指定打印机
config.setDisplayPrintDialog(showDialog); // 不显示打印对话框
config.setDisplayPageDialog(false); // 不显示页面设置对话框
PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
if (printtimes == null) printtimes=1;
attributes.add(new Copies(printtimes)); // 打印份数
// 修正:只有当papersize不为null时设置纸张大小
if (papersize != null) {
MediaSizeName mediaSize = getMediaSize(papersize);
if (mediaSize != null) { // 额外检查,确保mediaSize有效
attributes.add(mediaSize);
} else {
log.warn("无效的纸张尺寸: {}", papersize);
}
}
// 可选:设置打印方向(横向)
if(Orientation)attributes.add(OrientationRequested.LANDSCAPE);
config.setPrintRequestAttributeSet(attributes);
// 执行打印
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setConfiguration(config);
exporter.exportReport();
}
/**
* 导出为PDF文件
*/
private static void exportToPdf(JasperPrint jasperPrint, String exportPath) throws JRException {
JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(exportPath));
exporter.exportReport();
}
/**
* 根据打印机名称查找打印机(支持模糊匹配)
*/
private static PrintService findPrintService(String printerName) {
// 获取所有可用打印机
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
if (printServices == null || printServices.length == 0) {
return null;
}
// 1. 打印机名称为null时,返回默认打印机
if (printerName == null || printerName.trim().isEmpty()) {
return PrintServiceLookup.lookupDefaultPrintService();
}
// 2. 模糊匹配打印机名称(包含关键字即可)
for (PrintService service : printServices) {
if (service.getName().contains(printerName)) {
return service;
}
}
return null;
}
// ------------------------------ 简化调用的重载方法(可选)------------------------------
/**
* 重载:导出PDF(简化参数,无需传入打印机名称)
*/
public static void exportToPdf(
String templateName,
Map<String, Object> parameters,
List<?> dataList,
String exportPath
) throws Exception {
printbase(null, templateName, parameters, dataList, true, exportPath,null,null,false,false);
}
/**
* 重载:直接打印(简化参数)
* @param printerName 打印机名称(可为null,null时使用默认打印机)
* @param templateName 模板名称(支持jrxml或jasper,放在resources/template目录下)
* @param parameters 非循环字段集合(报表参数,如标题、日期等)
* @param dataList 循环体数据(List集合,每条数据对应detail区域一行)
*/
public static void print(
String printerName,
String templateName,
Map<String, Object> parameters,
List<?> dataList
) throws Exception {
printbase(printerName, templateName, parameters, dataList, false, null,null,null,false,false);
}
/**
* 重载:直接打印(简化参数)
* @param printerName 打印机名称(可为null,null时使用默认打印机)
* @param templateName 模板名称(支持jrxml或jasper,放在resources/template目录下)
* @param dataList 循环体数据(List集合,每条数据对应detail区域一行)
*/
public static void print(
String printerName,
String templateName,
List<?> dataList
) throws Exception {
print(printerName, templateName, null, dataList);
}
/**
* 重载:直接打印(简化参数)
* @param printerName 打印机名称(可为null,null时使用默认打印机)
* @param templateName 模板名称(支持jrxml或jasper,放在resources/template目录下)
* @param parameters 非循环字段集合(报表参数,如标题、日期等)
*/
public static void print(
String printerName,
String templateName,
Map<String, Object> parameters
) throws Exception {
print(printerName, templateName, parameters, null);
}
/**
* 重载:直接打印(使用默认打印机)
* @param templateName 模板名称(支持jrxml或jasper,放在resources/template目录下)
* @param parameters 非循环字段集合(报表参数,如标题、日期等)
*/
public static void print(
String templateName,
Map<String, Object> parameters
) throws Exception {
print(null, templateName, parameters, null);
}
/**
* 重载:直接打印(使用默认打印机)
* @param templateName 模板名称(支持jrxml或jasper,放在resources/template目录下)
* @param dataList 循环体数据(List集合,每条数据对应detail区域一行)
*/
public static void print(
String templateName,
List<?> dataList
) throws Exception {
print(null, templateName, null, dataList);
}
// 预定义字符串到 MediaSizeName 的映射
private static final Map<String, MediaSizeName> SIZE_MAP = new HashMap<>();
static {
SIZE_MAP.put("A0", MediaSizeName.ISO_A0);
SIZE_MAP.put("A1", MediaSizeName.ISO_A1);
SIZE_MAP.put("A2", MediaSizeName.ISO_A2);
SIZE_MAP.put("A3", MediaSizeName.ISO_A3);
SIZE_MAP.put("A4", MediaSizeName.ISO_A4);
SIZE_MAP.put("A5", MediaSizeName.ISO_A5);
SIZE_MAP.put("A6", MediaSizeName.ISO_A6);
// 可添加更多映射(如 US Letter、Legal 等)
}
public static MediaSizeName getMediaSize(String sizeStr) {
if (sizeStr == null) return null;
return SIZE_MAP.get(sizeStr.toUpperCase());
}
/**
* 编译jrxml并保存到resources/templates同级目录
* @param jrxmlFileName 模板文件名(不带扩展名,如"barcode")
* @throws Exception 编译或IO异常
*/
public static void compileAndSave(String jrxmlFileName) throws Exception {
// 1. 定义文件名和路径
String jrxmlName = jrxmlFileName + ".jrxml"; // jrxml文件名
String jasperName = jrxmlFileName + ".jasper"; // 编译后文件名
// 2. 获取resources/templates下的jrxml输入流
InputStream jrxmlStream = JasperReportUtil.class
.getClassLoader()
.getResourceAsStream(templatep + jrxmlName);
if (jrxmlStream == null) {
throw new Exception("未找到jrxml模板:"+templatep + jrxmlName);
}
// 3. 编译jrxml为JasperReport对象
JasperReport jasperReport = JasperCompileManager.compileReport(jrxmlStream);
// 4. 确定输出目录(resources/templates的同级目录,即classes/templates)
File outputDir = getTemplateOutputDir();
if (!outputDir.exists()) {
outputDir.mkdirs(); // 目录不存在则创建
}
// 5. 输出jasper文件到目标目录
File jasperFile = new File(outputDir, jasperName);
JRSaver.saveObject(jasperReport, jasperFile); // 保存编译结果
System.out.println("编译成功:" + jasperFile.getAbsolutePath());
}
/**
* 获取模板输出目录(resources/templates编译后的目录)
*/
private static File getTemplateOutputDir() throws URISyntaxException {
// 获取templates目录的URL(开发时是resources/templates,运行时是classes/templates)
URL templateUrl = JasperReportUtil.class.getClassLoader().getResource(template);
if (templateUrl == null) {
// 如果templates目录不存在,创建在classes目录下
URL classesUrl = JasperReportUtil.class.getClassLoader().getResource("");
return new File(classesUrl.toURI().getPath() + File.separator + template);
}
// 返回templates目录的File对象
return new File(templateUrl.toURI());
}
}

View File

@ -4,118 +4,32 @@ package com.czlis.interfaceCommon.utils;
import com.czlis.common.config.RuoYiConfig; import com.czlis.common.config.RuoYiConfig;
import com.czlis.interfaceCommon.pojo.entity.MZBarCodeParam; import com.czlis.interfaceCommon.pojo.entity.MZBarCodeParam;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.export.JRPrintServiceExporter;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimplePrintServiceExporterConfiguration;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import net.sf.jasperreports.engine.JasperPrint;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.standard.MediaSizeName;
@Component @Component
@Slf4j @Slf4j
public class ReportUtil { public class ReportUtil {
public void printBarCode(MZBarCodeParam mzBarCodeParam) { public void printBarCode(MZBarCodeParam mzBarCodeParam) {
String jrxmlPath = RuoYiConfig.getProfile() + "\\barcode.jrxml";
String jasperPath = RuoYiConfig.getProfile() + "\\barcode.jasper";
// 获取类路径(resources 目录)
String property = System.getProperty("user.dir");
System.out.println("打印路径:"+property);
//String resourcesPath = property + "\\lis-" + File.separator + jasperPath;
//编译模板
try { try {
JasperCompileManager.compileReportToFile(jrxmlPath,jasperPath);
//构造数据 //构造数据
Map parameters = new HashMap(); Map parameters = new HashMap();
parameters.put("barcode",mzBarCodeParam.getSqh()); parameters.put("barcode",mzBarCodeParam.getSqh());
parameters.put("line1",mzBarCodeParam.getBrxm() + " " + mzBarCodeParam.getBrxb() + " " + mzBarCodeParam.getNl()); parameters.put("line1",mzBarCodeParam.getBrxm() + " " + mzBarCodeParam.getBrxb() + " " + mzBarCodeParam.getNl());
parameters.put("line2",mzBarCodeParam.getSfxmmc()); parameters.put("line2",mzBarCodeParam.getSfxmmc());
//填充数据 JasperReportUtil.print(RuoYiConfig.getMzPrintName(),"barcode",parameters);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperPath, parameters, new JREmptyDataSource());
//输出文件
// String pdfPath = "E:\\barcode.pdf";
// JasperExportManager.exportReportToPdfFile(jasperPrint,pdfPath);
// printPdfFile(pdfPath);
//打印条码
//JasperPrintManager.printReport(jasperPrint, false);
print(jasperPrint,false, RuoYiConfig.getMzPrintName());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
log.error("打印条码报错,条码号:{}",mzBarCodeParam.getSqh(),e); log.error("打印条码报错,条码号:{}",mzBarCodeParam.getSqh(),e);
} }
} }
/**
* 6.8.0版本专用:指定打印机打印报表
* @param jasperPrint 报表对象
* @param showDialog 是否显示打印对话框
* @param printerName 目标打印机名称(支持模糊匹配)
* @throws Exception 打印异常
*/
public static void print(JasperPrint jasperPrint, boolean showDialog, String printerName) throws Exception {
// 1. 获取系统中所有可用打印机
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
if (printServices == null || printServices.length == 0) {
throw new RuntimeException("未检测到任何可用打印机");
}
// 2. 查找目标打印机(6.8.0版本兼容的遍历方式)
PrintService targetService = null;
for (PrintService service : printServices) {
String serviceName = service.getName();
// 精确匹配可改为:serviceName.equals(printerName)
if (serviceName.contains(printerName)) {
targetService = service;
break;
}
}
if (targetService == null) {
throw new RuntimeException("未找到名称包含 [" + printerName + "] 的打印机");
}
// 3. 配置打印参数(6.8.0版本的标准API)
JRPrintServiceExporter exporter = new JRPrintServiceExporter();
SimplePrintServiceExporterConfiguration config = new SimplePrintServiceExporterConfiguration();
// 设置目标打印机
config.setPrintService(targetService);
// 控制是否显示系统打印对话框(6.8.0版本此参数有效)
config.setDisplayPrintDialog(showDialog);
// 不显示页面设置对话框(如需显示可改为true)
config.setDisplayPageDialog(false);
// 4. 设置打印属性(份数、纸张等)
PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
attributes.add(new Copies(1)); // 打印份数
attributes.add(MediaSizeName.ISO_A4); // 纸张大小A4
// 可选:设置打印方向(横向)
// attributes.add(OrientationRequested.LANDSCAPE);
config.setPrintRequestAttributeSet(attributes);
// 5. 绑定报表并执行打印(6.8.0版本的标准导出方式)
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setConfiguration(config);
exporter.exportReport();
}
} }

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.9.0.final using JasperReports Library version 6.9.0-cb8f9004be492ccc537180b49c026951f4220bf3 --> <!-- Created with Jaspersoft Studio version 6.9.0.final using JasperReports Library version 6.9.0-cb8f9004be492ccc537180b49c026951f4220bf3 -->
<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="barcode" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="fbec7cd4-b278-4201-aae2-7cfd7e7b953c"> <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="barcode" pageWidth="141" pageHeight="85" columnWidth="141" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0" uuid="fbec7cd4-b278-4201-aae2-7cfd7e7b953c">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/> <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
<property name="com.jaspersoft.studio.unit." value="cm"/>
<parameter name="barcode" class="java.lang.String"/> <parameter name="barcode" class="java.lang.String"/>
<parameter name="line1" class="java.lang.String"/> <parameter name="line1" class="java.lang.String"/>
<parameter name="line2" class="java.lang.String"/> <parameter name="line2" class="java.lang.String"/>
@ -12,41 +13,31 @@
<band splitType="Stretch"/> <band splitType="Stretch"/>
</background> </background>
<title> <title>
<band height="184" splitType="Stretch"> <band height="85" splitType="Stretch">
<componentElement>
<reportElement x="6" y="6" width="130" height="32" uuid="e6aa5ef9-8f70-45cb-969e-8484f75390bb">
<property name="com.jaspersoft.studio.unit.width" value="pixel"/>
<property name="com.jaspersoft.studio.unit.x" value="px"/>
</reportElement>
<jr:barbecue xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd" type="Code128" drawText="false" checksumRequired="false">
<jr:codeExpression><![CDATA[$P{barcode}]]></jr:codeExpression>
</jr:barbecue>
</componentElement>
<textField> <textField>
<reportElement x="17" y="23" width="100" height="15" uuid="925826fe-f359-43dd-b4c2-aa5fee83be67"/> <reportElement x="7" y="30" width="128" height="15" uuid="9029e1d0-5307-4d60-8098-225825491e85">
<textElement>
<font fontName="华文宋体" size="10"/>
</textElement>
<textFieldExpression><![CDATA[$P{barcode}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="7" y="39" width="128" height="15" uuid="9029e1d0-5307-4d60-8098-225825491e85">
<property name="com.jaspersoft.studio.unit.height" value="px"/> <property name="com.jaspersoft.studio.unit.height" value="px"/>
</reportElement> </reportElement>
<textElement> <textElement>
<font fontName="华文宋体" size="10"/> <font fontName="华文宋体" size="9"/>
</textElement> </textElement>
<textFieldExpression><![CDATA[$P{line1}]]></textFieldExpression> <textFieldExpression><![CDATA[$P{line1}]]></textFieldExpression>
</textField> </textField>
<textField> <textField>
<reportElement x="6" y="56" width="130" height="15" uuid="902afe45-cfe9-4095-9a76-b0ea517a08b3"> <reportElement x="6" y="45" width="130" height="15" uuid="902afe45-cfe9-4095-9a76-b0ea517a08b3">
<property name="com.jaspersoft.studio.unit.height" value="px"/> <property name="com.jaspersoft.studio.unit.height" value="px"/>
</reportElement> </reportElement>
<textElement> <textElement>
<font fontName="华文宋体" size="10"/> <font fontName="华文宋体" size="9"/>
</textElement> </textElement>
<textFieldExpression><![CDATA[$P{line2}]]></textFieldExpression> <textFieldExpression><![CDATA[$P{line2}]]></textFieldExpression>
</textField> </textField>
<componentElement>
<reportElement x="6" y="0" width="100" height="30" uuid="d1408edf-988b-4360-8b54-67870f14b43f"/>
<jr:Code128 xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd">
<jr:codeExpression><![CDATA[$P{barcode}]]></jr:codeExpression>
</jr:Code128>
</componentElement>
</band> </band>
</title> </title>
</jasperReport> </jasperReport>

View File

@ -53,4 +53,8 @@ public class MZCXController extends BaseController {
public Result printAll(@RequestBody List<String> sqhs){ public Result printAll(@RequestBody List<String> sqhs){
return mzcxService.printAll(sqhs); return mzcxService.printAll(sqhs);
} }
@PostMapping("/printBackpaper")
public Result printBackpaper(@RequestBody List<String> sqhs){
return mzcxService.printBackpaper(sqhs);
}
} }

View File

@ -10,4 +10,5 @@ public interface MZCXService {
Result queryPatList(); Result queryPatList();
Result printSQD(String sqh); Result printSQD(String sqh);
Result printAll(List<String> sqhs); Result printAll(List<String> sqhs);
Result printBackpaper(List<String> sqhs);
} }

View File

@ -128,4 +128,10 @@ public class MZCXServiceImpl implements MZCXService {
return new Result("0","打印成功!"); return new Result("0","打印成功!");
} }
@Override
public Result printBackpaper(List<String> sqhs){
log.info("aaaaa: {}", sqhs);
return new Result("0","打印成功!");
}
} }