有时候我们在项目中需要生成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 -> {//对应每行图片的modelFraudReportOrderEvidenceImage 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文件就搞定了,以上供大家参考

JasperReport pdf报表中插入图片(显示图片)相关推荐

  1. 如何快速在PDF文件中插入图片

    在 PDF文件中插入图片我优先想到了 Adobe Acrobat DC,胜任此项工作完全 OK.但是有个问题,Acrobat 会自动识别 PDF 中的文字.如果有手写字迹经过 Acrobat 识别再保 ...

  2. 向pdf文件中插入图片及文字 java实现

    向pdf文件中插入图片及文字 引入itextpdf相关依赖 <!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf --> ...

  3. 帆软报表导出Word不显示图片问题解决

    帆软报表导出Word不显示图片问题解决 问题:从网页端导出Word版 有的图片不显示 原因:帆软报表悬浮元素不支持Word导出 解决办法:把悬浮元素的图片保存在本地,选中单元格,设置单元格元素为插入图 ...

  4. mfc中插入PNG透明图片

    mfc中插入PNG透明图片 记录下在mfc中插入png透明图片的方法 新建项目 在对话框界面中插入两个 Picture Control 在MFC_pngDlg.h中添加 在MFC_pngDlg.cpp ...

  5. rp原型中鼠标悬停显示图片_悬停状态原型4种方式

    rp原型中鼠标悬停显示图片 There are tons of options available for UX designers to prototype a user experience an ...

  6. 在可编辑div中插入文字或图片的问题解决思路

    最近在网上碰到一个人问了我一个问题,在可编辑div中插入文字或者图片.因为web在线编辑器我从来只是用,基本不会去研究源代码.后来正好一个在线聊天web项目中也要用到这个功能,我就特地看看了代码. 基 ...

  7. OpenGL3.x,4.x中使用FreeImage显示图片的BUG-黑色,或颜色分量顺序错乱

    OpenGL3.x,4.x中使用FreeImage显示图片的BUG-黑色,或颜色分量顺序错乱 1 //参照FreeImage官网给出的CTextrueManager写的加载函数 2 //官方给的例子是 ...

  8. Qt 实现QT控件中的QLabel显示图片并自适应显示

    一.需求 实现QT控件中的QLabel显示图片,并自适应显示. 二.代码 QImage Image; Image.load(":/image/image/logo.jpg"); Q ...

  9. Ubuntu中Python无法显示图片

    Ubuntu中Python无法显示图片 显示错误是UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, ...

最新文章

  1. Vim的行号、语法显示等设置(.vimrc文件的配置)以及乱码解决
  2. 利用python爬虫(part13)--requests模块之requests.get的参数们
  3. case when then的用法
  4. C中关于存储类的理解
  5. java HashMap实现中文分词器 应用:敏感词过滤实现
  6. 三星Galaxy Note20系列再遭减配:100倍变焦也没了
  7. OpenShift 4 - 安装部署 Ansible Automation Platform 4.x 控制台
  8. 6. 成交量基础分析
  9. Oracle笔记(一) Oracle简介及安装
  10. JAVA控制台扑克牌游戏,洗牌,发牌,比较大小
  11. PHP最常用的2种设计模式工厂模式和单例模式
  12. 解释说明CCIE考试中的RIP问题
  13. SQL常用语句(普通查询+条件查询)
  14. 408计算机考研真题推荐,2017计算机408考研真题.pdf
  15. [转帖]国产操作系统概念及历史,目前国产操作系统有哪些?
  16. 网络安全实验5 证书应用和证书管理
  17. 服务器虚拟化三种架构,X86虚拟化之三种服务器虚拟化战略架构
  18. web前端CSS---关于text-align设置为justify的相关内容
  19. 挂起和阻塞区别?sleep()和wait()的区别?
  20. 1688图片批量采集技巧

热门文章

  1. C语言字符串冒泡排序
  2. (61)-- 用代理IP爬取网页
  3. 国产禁用化妆品(转载)
  4. 图像与机器学习-1-梯度下降法与ubuntu
  5. CAN总线的终端电阻一定要120Ω吗?
  6. 基于SpringBoot+Vue 实现准妈妈孕期交流平台【源码+论文+演示视频+包运行成功】
  7. A2DP Hardware Offload
  8. 每日英语--Week 2
  9. Python制作校庆海报
  10. C++ 11 deleted函数