springboot集成ireport(JasperPrint)模板实现打印

之前的项目中用到采用ireport打印,重构的bs架构项目不想重新画打印模板,准备继续沿用,记录springboot集成ireport实现打印。


 0.添加maven依赖

        <!--jasper框架依赖开始-->
        <dependency>
            <groupId>net.sf.jasperreports</groupId>
            <artifactId>jasperreports</artifactId>
            <version>6.17.0</version>
        </dependency>
        <dependency>
            <groupId>net.sf.jasperreports</groupId>
            <artifactId>jasperreports-fonts</artifactId>
            <version>6.17.0</version>
        </dependency>
        <dependency>
            <groupId>net.sf.barcode4j</groupId>
            <artifactId>barcode4j</artifactId>
            <version>2.1</version>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.barbecue</groupId>
            <artifactId>barbecue</artifactId>
            <version>1.5-beta1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-bridge</artifactId>
            <version>1.14</version>
        </dependency>
        <!--jasper框架依赖结束-->

1.添加配置文件:src/main/resources/jasperreports_extension.properties

net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.lobstertwo=fonts/fonts.xml
net.sf.jasperreports.awt.ignore.missing.font=true

2.添加字体配置src/main/resources/fonts/fonts.xml 以及字体包TTF文件(TTC测试不行)

 

<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
    <!--<fontFamily name="Lobster Two">-->
    <!--<normal>lobstertwo/LobsterTwo-Regular.otf</normal>-->
    <!--<bold>lobstertwo/LobsterTwo-Bold.otf</bold>-->
    <!--<italic>lobstertwo/LobsterTwo-Italic.otf</italic>-->
    <!--<boldItalic>lobstertwo/LobsterTwo-BoldItalic.otf</boldItalic>-->
    <!--<pdfEncoding>Identity-H</pdfEncoding>-->
    <!--<pdfEmbedded>true</pdfEmbedded>-->
    <!--<!–-->
    <!--<exportFonts>-->
    <!--<export key="net.sf.jasperreports.html">'Lobster Two', 'Times New Roman', Times, serif</export>-->
    <!--</exportFonts>-->
    <!--–>-->
    <!--</fontFamily>-->
    <fontFamily name="华文宋体">
        <normal>fonts/stsong.TTF</normal>
        <bold>fonts/stsong.TTF</bold>
        <italic>fonts/stsong.TTF</italic>
        <boldItalic>fonts/stsong.TTF</boldItalic>
        <pdfEncoding>Identity-H</pdfEncoding>
        <pdfEmbedded>true</pdfEmbedded>
        <exportFonts>
            <export key="net.sf.jasperreports.html">'华文宋体', Arial, Helvetica, sans-serif</export>
            <export key="net.sf.jasperreports.xhtml">'华文宋体', Arial, Helvetica, sans-serif</export>
        </exportFonts>
        <!--
        <locales>
            <locale>en_US</locale>
            <locale>de_DE</locale>
        </locales>
        -->
    </fontFamily>
    <fontFamily name="宋体">
        <normal>fonts/SimSun.ttf</normal>
        <bold>fonts/SimSun.ttf</bold>
        <italic>fonts/SimSun.ttf</italic>
        <boldItalic>fonts/SimSun.ttf</boldItalic>
        <pdfEncoding>Identity-H</pdfEncoding>
        <pdfEmbedded>true</pdfEmbedded>
        <exportFonts>
            <export key="net.sf.jasperreports.html">'宋体', Arial, Helvetica, sans-serif</export>
            <export key="net.sf.jasperreports.xhtml">'宋体', Arial, Helvetica, sans-serif</export>
        </exportFonts>
        <!--
        <locales>
            <locale>en_US</locale>
            <locale>de_DE</locale>
        </locales>
        -->
    </fontFamily>
    <fontFamily name="微软雅黑">
        <normal>fonts/msyh.ttf</normal>
        <bold>fonts/msyh.ttf</bold>
        <italic>fonts/msyh.ttf</italic>
        <boldItalic>fonts/msyh.ttf</boldItalic>
        <pdfEncoding>Identity-H</pdfEncoding>
        <pdfEmbedded>true</pdfEmbedded>
        <exportFonts>
            <export key="net.sf.jasperreports.html">'微软雅黑', Arial, Helvetica, sans-serif</export>
            <export key="net.sf.jasperreports.xhtml">'微软雅黑', Arial, Helvetica, sans-serif</export>
        </exportFonts>
        <!--
        <locales>
            <locale>en_US</locale>
            <locale>de_DE</locale>
        </locales>
        -->
    </fontFamily>
</fontFamilies>

3.编写公共方法,生成pdf

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.springframework.http.*;

import java.io.InputStream;
import java.util.Collection;
import java.util.Map;

/**
 * 
 * @date 2025年05月12日 下午5:33
 */
public class JasperPrintUtils {
    /**
     *
     * @param is 编译的jasper文件的InputStream
     * @param map 全局变量的map
     * @param beanCollection 动态扩展的list数据
     * @return net.sf.jasperreports.engine.JasperPrint
     */
    private static JasperPrint renderTemplates(InputStream is, Map<String, Object> map, Collection<?> beanCollection) throws JRException {
        JRBeanCollectionDataSource jrBeanCollectionDataSource = new JRBeanCollectionDataSource(beanCollection);
        return JasperFillManager.fillReport(is, map, jrBeanCollectionDataSource);
    }

    /**
     * 封装返回字节文件
     * 
     * @param jasperPrint
     * @return net.sf.jasperreports.engine.JasperPrint
     */
    private static ResponseEntity<byte[]> exportPdfByte(JasperPrint jasperPrint) throws JRException {
        byte[] bytes = JasperExportManager.exportReportToPdf(jasperPrint);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_PDF);
        headers.setContentDisposition(ContentDisposition.inline().filename("report.pdf").build());
        headers.setContentLength(bytes.length);

        return ResponseEntity
                .status(HttpStatus.OK)
                .headers(headers)
                .body(bytes);
    }

    /**
     * 封装打印模板返回字节文件
     * 
     * @param is 编译的jasper文件的InputStream
     * @param t 全局变量的对象
     * @param beanCollection 动态扩展的list数据
     * @return org.springframework.http.ResponseEntity<byte[]>
     */
    public static ResponseEntity<byte[]> getreportToPdf(InputStream is,
                                                        Object obj,
                                                        Collection<?> beanCollection) {
        try {
            // 下面对象转map的公共方法
            Map<String, Object> map = BeanMapUtils.beanToMap(obj);
            return exportPdfByte(renderTemplates(is, map, beanCollection));
        }catch (JRException e) {
            e.printStackTrace();
        }
    }
}

//****************将对象属性转化为map集合*********************/
import org.springframework.cglib.beans.BeanMap;

import java.util.HashMap;
import java.util.Map;

public class BeanMapUtils {

    /**
     * 将对象属性转化为map集合
     */
    public static <T> Map<String, Object> beanToMap(T bean) {
        Map<String, Object> map = new HashMap<>();
        if (bean != null) {
            BeanMap beanMap = BeanMap.create(bean);
            for (Object key : beanMap.keySet()) {
                map.put(key+""  , beanMap.get(key));
            }
        }
        return map;
    }
}

4.调用案例

@PostMapping("/pdfReport")
    public ResponseEntity<byte[]> pdfReport() throws Exception {
        // 获取模板(工程目录)
//        Resource resource = resourceLoader.getResource("classpath:static/jasper/pickingMarkZh_30_Color.jasper");
//        InputStream is = resource.getInputStream();
        // 获取模板(存储服务器)
        String reportName = "pickingMarkZh_30_Color.jasper";
        InputStream is = minioService.getFileInputStream(reportName);
        //造数据,g 全局数据(需创建全局参数对象)
        ExportTestHeadVO exportTestVO = new ExportTestHeadVO();
        exportTestVO.setPmax("425W");
        exportTestVO.setPalletNo("LRA004131230508762");
        exportTestVO.setModuleType("LR5-54HTH-425M");
        exportTestVO.setBoxType("PV-LR07A(+1200mm/-1200mm/EV02)-三分体");
        exportTestVO.setCellType("Hi-MO4 NEW 6BB");
        exportTestVO.setCurrentClass("M");
        exportTestVO.setPickSize("1767*1130*1243mm");
        exportTestVO.setFrameColor("黑色/Black");
        exportTestVO.setTotalWigth("20.8kg");
        exportTestVO.setCellColor("中蓝/medium blue");
        exportTestVO.setRemark("Test");
        exportTestVO.setCode("1");
        //造数据,v 局部数据(需创建局部参数对象)
        List<ExportTestLineVO> exportTestLineVOList = new ArrayList<>();
        for (int i = 0; i < 36; i++) {
            ExportTestLineVO exportTestLineVO = new ExportTestLineVO();
            exportTestLineVO.setNo(String.valueOf(i+1));
            exportTestLineVO.setModuleId("LRP00413123050190649"+(i+1));
            exportTestLineVOList.add(exportTestLineVO);
        }

        return JasperPrintUtils.getreportToPdf(is, exportTestVO, exportTestLineVOList);
    }

5.前端调用

export function printTest1() {
  return bizRequest({
    responseType: 'blob',
    url: '/api/biz/demo/pdfReport',
    method: 'post'
  }).then(response => {
    // 提取文件名
    const blob = new Blob([response.data], { type: response.data.type });

    handleBlobPrint(blob);
  });
}

export function handleBlobPrint(blob: Blob) {
  const { closeLoading } = useAppStore();
  closeLoading();
  // 生成临时 URL
  const fileURL = window.URL.createObjectURL(blob);

  // 创建隐藏的 iframe
  const iframe = document.createElement('iframe');
  iframe.style.display = 'none';
  iframe.src = fileURL;
  document.body.appendChild(iframe);

  // 等待 iframe 加载完成后再触发打印
  iframe.onload = () => {
    const contentWindow = iframe.contentWindow as Window;

    contentWindow.addEventListener('afterprint', () => {
      document.body.removeChild(iframe);
      window.URL.revokeObjectURL(fileURL);
    });

    contentWindow.print();
  };
}

6.注意事项

ireport中动态拓展字段的描述必须恢复默认设置,否则会提示找不到该变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

k_trouble

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值