IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> JasperReport pdf报表中插入图片(显示图片) -> 正文阅读

[Java知识库]JasperReport pdf报表中插入图片(显示图片)

有时候我们在项目中需要生成pdf文件(详细可看我的另一篇文章),并且pdf中需要动态的显示需要的图片,使用JasperReport可以很便捷的完成我们的诉求。比如我们需要生成如下的pdf文件:
在这里插入图片描述
接下来演示怎么实现:

设计模板

按自己的需求将image元素拖到指定的位置,拖拽image元素到报表设计区域的时候会让选择图片的资源路径,按默认配置即可,如下图
在这里插入图片描述
调节图片大小,以及每行展示的数量(detail栏的元素会根据数据源去遍历展示),如下图:
在这里插入图片描述
然后最重要的就是配置上图中的Expression表达式,即告诉框架要从哪里获取图片资源,这里我是通过字节数组输入流创建图片的,完整的Expression表达式如下,可以直接粘贴使用。说明:$ F{reportDescImage}是图片的字节数组对应的Base64编码后的字符串,所以表达式中要对$F{reportDescImage}进行Base64解码,转换为图片原来的字节数组,这样框架就可以渲染出图片了

new ByteArrayInputStream(org.apache.commons.codec.binary.Base64.decodeBase64($F{reportDescImage}.getBytes()))

代码实现

核心代码如下:

public void exportReportOrder(Integer reportId, HttpServletResponse servletResponse) {
        //查询自己需要的业务数据
        ReportOrderDetailVO detailVO = this.getReportOrderDetail(reportId);
        OutputStream outputStream;
        try {
            outputStream = servletResponse.getOutputStream();
            String fileName = reportOrderConverter.getPdfFileName(detailVO);
            //设置http的文件类型及编码方式
            servletResponse.setContentType("application/pdf;charset=utf-8");
            //设置下载的文件名称 名称含有中文的话需要用URLEncoder进行编码
            servletResponse.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));

            Map<String, String> reportTypeToNameMap = reportTypeEnumService.getCodeToNameMap();
            ExportFraudReportOrderResponse response = reportOrderConverter.assembleFraudReportOrder(detailVO, reportTypeToNameMap);
            //组装模板中需要的参数 用于填充模板中通过$P{xxx}声明的参数
            Map<String, Object> params = reportOrderConverter.assembleReportParams(response);

            List<FraudReportOrderEvidenceImage> imageList = reportOrderConverter.getImageResources(detailVO);
            //设置JasperReport的数据源 我用的是Json类型的数据源(数据源中的数据用于填充模板中detail区域的通过$F{XXX}指定的参数)
            JsonDataSource jsonDataSource = new JsonDataSource(new ByteArrayInputStream(JSON.toJSONString(imageList).getBytes(StandardCharsets.UTF_8)));

            boolean hasImage = reportOrderConverter.hasImage(detailVO);
            if (hasImage) {
                fileGenerateService.generates(EnumFileMeta.PDF_4_FRAUD_REPORT, outputStream, params, jsonDataSource);
            } else {
                fileGenerateService.generates(EnumFileMeta.PDF_4_FRAUD_REPORT_WITHOUT_IMAGE, outputStream, params, jsonDataSource);
            }
        } catch (IOException io) {
            log.error("获取http输出流失败", io);
            throw new ServiceResponseException("获取http输出流失败");
        } catch (Exception e) {
            log.error("生成报告单失败", e);
            throw new ServiceResponseException("生成报告单失败");
        }
    }

public List<FraudReportOrderEvidenceImage> getImageResources(ReportOrderDetailVO detailVO) {
        if (!this.hasImage(detailVO)) {
            return this.buildEmptyImage();
        }

        List<String> imageUrls = detailVO.getResourceList().stream()
                .filter(f -> EnumResourceType.图片.getCode().equals(f.getResourceType()))
                .map(m -> {
                    if (!StringUtils.startsWith(m.getResourceUrl(), HTTPS)) {
                        return HTTPS + m.getResourceUrl();
                    }
                    return m.getResourceUrl();
                }).collect(Collectors.toList());

        log.info("image urls: {}", imageUrls);
        List<FraudReportOrderEvidenceImage> images = new ArrayList<>();

        //将查询到的图片url按照报表模板中设置的图片每行的数量进行划分
        // 模板中设置的一行为4个图片 所以此处我们以4为单位划分
        Lists.partition(imageUrls, 4).forEach(items -> {
            //对应每行图片的model
            FraudReportOrderEvidenceImage image = new FraudReportOrderEvidenceImage();
            for (int i = 0; i < items.size(); i++) {

                //使用Spring的RestTemplate API去读取图片 读取图片的字节数组
                byte[] imageBytes = restTemplate.getForObject(items.get(i), byte[].class);
                if (i == 0) {
                    image.setReportDescImage(this.byte2String(imageBytes));
                    continue;
                }
                if (i == 1) {
                    image.setReportDescImage2(this.byte2String(imageBytes));
                    continue;
                }
                if (i == 2) {
                    image.setReportDescImage3(this.byte2String(imageBytes));
                    continue;
                }
                if (i == 3) {
                    image.setReportDescImage4(this.byte2String(imageBytes));
                }
            }
            images.add(image);
        });

        return images;
    }

    public boolean hasImage(ReportOrderDetailVO detailVO) {
        if (Objects.isNull(detailVO) || CollectionUtils.isEmpty(detailVO.getResourceList())) {
            return false;
        }

        List<String> imageUrls = detailVO.getResourceList().stream()
                .filter(f -> EnumResourceType.图片.getCode().equals(f.getResourceType()))
                .map(m -> m.getResourceUrl())
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(imageUrls)) {
            return false;
        }

        return true;
    }

    private List<FraudReportOrderEvidenceImage> buildEmptyImage() {
        FraudReportOrderEvidenceImage image = new FraudReportOrderEvidenceImage();
        byte[] empty = new byte[0];
        String emptyImage = new String(org.apache.commons.codec.binary.Base64.encodeBase64(empty), StandardCharsets.UTF_8);
        image.setReportDescImage(emptyImage);
        image.setReportDescImage2(emptyImage);
        image.setReportDescImage3(emptyImage);
        image.setReportDescImage4(emptyImage);
        return Collections.singletonList(image);
    }

    /**
     * 字节数组编码为Base64字符串
     * @param imageBytes
     * @return
     */
    private String byte2String(byte[] imageBytes) {
        imageBytes = Objects.isNull(imageBytes) ? new byte[0] : imageBytes;
        String imageStr = new String(org.apache.commons.codec.binary.Base64.encodeBase64(imageBytes), StandardCharsets.UTF_8);
        return imageStr;
    }

至此生成含图片的pdf文件就搞定了,以上供大家参考

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 23:11:18  更:2022-04-01 23:15:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:25:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码