diff --git a/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/JasperReportUtil.java b/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/JasperReportUtil.java new file mode 100644 index 0000000..389b7f2 --- /dev/null +++ b/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/JasperReportUtil.java @@ -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 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 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 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 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 parameters + ) throws Exception { + print(printerName, templateName, parameters, null); + } + /** + * 重载:直接打印(使用默认打印机) + * @param templateName 模板名称(支持jrxml或jasper,放在resources/template目录下) + * @param parameters 非循环字段集合(报表参数,如标题、日期等) + */ + public static void print( + String templateName, + Map 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 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()); + } + +} \ No newline at end of file diff --git a/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/ReportUtil.java b/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/ReportUtil.java index 41ddef4..63ea612 100644 --- a/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/ReportUtil.java +++ b/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/ReportUtil.java @@ -4,118 +4,32 @@ package com.czlis.interfaceCommon.utils; import com.czlis.common.config.RuoYiConfig; import com.czlis.interfaceCommon.pojo.entity.MZBarCodeParam; 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 javax.print.attribute.HashPrintRequestAttributeSet; -import javax.print.attribute.PrintRequestAttributeSet; -import javax.print.attribute.standard.Copies; import java.util.HashMap; 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 @Slf4j public class ReportUtil { - - 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 { - JasperCompileManager.compileReportToFile(jrxmlPath,jasperPath); //构造数据 Map parameters = new HashMap(); parameters.put("barcode",mzBarCodeParam.getSqh()); parameters.put("line1",mzBarCodeParam.getBrxm() + " " + mzBarCodeParam.getBrxb() + " " + mzBarCodeParam.getNl()); parameters.put("line2",mzBarCodeParam.getSfxmmc()); - //填充数据 - 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()); + JasperReportUtil.print(RuoYiConfig.getMzPrintName(),"barcode",parameters); } catch (Exception e) { e.printStackTrace(); 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(); - } - } diff --git a/lis-interfaceCommon/src/main/resources/template/barcode.jasper b/lis-interfaceCommon/src/main/resources/template/barcode.jasper deleted file mode 100644 index f3c0730..0000000 Binary files a/lis-interfaceCommon/src/main/resources/template/barcode.jasper and /dev/null differ diff --git a/lis-interfaceCommon/src/main/resources/template/barcode.jrxml b/lis-interfaceCommon/src/main/resources/template/barcode.jrxml index d608558..ea3a28a 100644 --- a/lis-interfaceCommon/src/main/resources/template/barcode.jrxml +++ b/lis-interfaceCommon/src/main/resources/template/barcode.jrxml @@ -1,7 +1,8 @@ - + + @@ -12,41 +13,31 @@ - <band height="184" 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> + <band height="85" splitType="Stretch"> <textField> - <reportElement x="17" y="23" width="100" height="15" uuid="925826fe-f359-43dd-b4c2-aa5fee83be67"/> - <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"> + <reportElement x="7" y="30" width="128" height="15" uuid="9029e1d0-5307-4d60-8098-225825491e85"> <property name="com.jaspersoft.studio.unit.height" value="px"/> </reportElement> <textElement> - <font fontName="华文宋体" size="10"/> + <font fontName="华文宋体" size="9"/> </textElement> <textFieldExpression><![CDATA[$P{line1}]]></textFieldExpression> </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"/> </reportElement> <textElement> - <font fontName="华文宋体" size="10"/> + <font fontName="华文宋体" size="9"/> </textElement> <textFieldExpression><![CDATA[$P{line2}]]></textFieldExpression> </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> diff --git a/mzcx/src/main/java/com/czlis/mzcx/controller/MZCXController.java b/mzcx/src/main/java/com/czlis/mzcx/controller/MZCXController.java index bc5bc24..d33360b 100644 --- a/mzcx/src/main/java/com/czlis/mzcx/controller/MZCXController.java +++ b/mzcx/src/main/java/com/czlis/mzcx/controller/MZCXController.java @@ -53,4 +53,8 @@ public class MZCXController extends BaseController { public Result printAll(@RequestBody List sqhs){ return mzcxService.printAll(sqhs); } + @PostMapping("/printBackpaper") + public Result printBackpaper(@RequestBody List sqhs){ + return mzcxService.printBackpaper(sqhs); + } } diff --git a/mzcx/src/main/java/com/czlis/mzcx/service/MZCXService.java b/mzcx/src/main/java/com/czlis/mzcx/service/MZCXService.java index 7bf8b55..e418dd7 100644 --- a/mzcx/src/main/java/com/czlis/mzcx/service/MZCXService.java +++ b/mzcx/src/main/java/com/czlis/mzcx/service/MZCXService.java @@ -10,4 +10,5 @@ public interface MZCXService { Result queryPatList(); Result printSQD(String sqh); Result printAll(List sqhs); + Result printBackpaper(List sqhs); } diff --git a/mzcx/src/main/java/com/czlis/mzcx/service/impl/MZCXServiceImpl.java b/mzcx/src/main/java/com/czlis/mzcx/service/impl/MZCXServiceImpl.java index 8dcb48e..f438c2f 100644 --- a/mzcx/src/main/java/com/czlis/mzcx/service/impl/MZCXServiceImpl.java +++ b/mzcx/src/main/java/com/czlis/mzcx/service/impl/MZCXServiceImpl.java @@ -128,4 +128,10 @@ public class MZCXServiceImpl implements MZCXService { return new Result("0","打印成功!"); } + @Override + public Result printBackpaper(List sqhs){ + log.info("aaaaa: {}", sqhs); + return new Result("0","打印成功!"); + } + }