java-EasyExcel模板导出
前言:
需求:根据自定义模板导出Excel,包含图片、表格,采用EasyExcel
提示:EasyExcel请使用 3.0 以上版本,
对图片操作最重要的类就是 WriteCellData<Void> 如果你的easyexcel没有这个类,说明你的版本太低,请升级到3.0以上
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.2.1</version>
</dependency>
实际代码:
Controller
@ApiOperation("excel导出详情")
@PostMapping("excelExport")
public void excelExport(HttpServletResponse response,
@ApiParam("id {\"id\":\"xxx\"}") @RequestBody Map<String, String> data) {
ExcelUitl.templateExport(response, researcherInformationService
.getDetail(data.get("id")));
}
ServiceImpl
public static String templateExport(HttpServletResponse response,ResearchDetailVo researchDetailVo) {
InputStream is = null;
try {
// 取出模板
is = ResourceUtil.getStream("classpath:templates/survey.xlsx");
Map<String, Object> map = new HashMap<>(10);
map.put("goOutDate", researchDetailVo.getGoOutDate());
map.put("userName", researchDetailVo.getUserName());
map.put("visitPlace", researchDetailVo.getVisitPlace());
map.put("marketTrends", researchDetailVo.getMarketTrends());
map.put("marketEnvironment", researchDetailVo.getMarketEnvironment());
map.put("partnerTrends", researchDetailVo.getPartnerTrends());
map.put("companyStatus", researchDetailVo.getCompanyStatus());
map.put("marketCompetition", researchDetailVo.getMarketCompetition());
map.put("feedback", researchDetailVo.getFeedback());
// 文件名称
String fileName = researchDetailVo.getUserName() + researchDetailVo.getGoOutDate()
+ "调研反馈信息表";
if (!ObjectUtils.isEmpty(researchDetailVo.getUrl())) {
//图片url转换为MultipartFile对象
// getUrl 是 List<String>
MultipartFile[] files = downloadImages(researchDetailVo.getUrl());
for (int i = 0; i < files.length; i++) {
MultipartFile file = files[i];
// 图像设置处理
WriteCellData<Void> voidWriteCellData = imageCells(file.getBytes());
map.put("img" + (i + 1), voidWriteCellData);
}
}
ExcelWriter excelWriter = EasyExcel.write(getOutputStream(fileName, response)).withTemplate(is).excelType(ExcelTypeEnum.XLSX).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
excelWriter.fill(map, writeSheet);
excelWriter.finish();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static WriteCellData<Void> imageCells(byte[] bytes) throws IOException {
WriteCellData<Void> writeCellData = new WriteCellData<>();
// 可以放入多个图片
List<ImageData> imageDataList = new ArrayList<>();
writeCellData.setImageDataList(imageDataList);
ImageData imageData = new ImageData();
imageDataList.add(imageData);
// 设置图片
imageData.setImage(bytes);
// 图片类型
//imageData.setImageType(ImageData.ImageType.PICTURE_TYPE_PNG);
// 上 右 下 左 需要留空,这个类似于 css 的 margin;
// 这里实测 不能设置太大 超过单元格原始大小后 打开会提示修复。暂时未找到很好的解法。
imageData.setTop(10);
imageData.setRight(10);
imageData.setBottom(10);
imageData.setLeft(10);
// * 设置图片的位置。Relative表示相对于当前的单元格index。first是左上点,last是对角线的右下点,这样确定一个图片的位置和大小。
// 目前填充模板的图片变量是images,index:row=CELL_COUNT,column=0。所有图片都基于此位置来设置相对位置
// 第1张图片相对位置
imageData.setRelativeFirstRowIndex(0);
imageData.setRelativeFirstColumnIndex(0);
imageData.setRelativeLastRowIndex(0);
imageData.setRelativeLastColumnIndex(0);
return writeCellData;
}
///为什么用线程池去实现 原因:当时项目文件储存用的是minio,由于服务器宽带非常低,导致几百K的图片都需要很久,多图片需要加载资源很久
public static MultipartFile[] downloadImages(List<String> imageUrls) {
// 创建一个固定大小的线程池
int poolSize = 5;
ThreadPoolExecutor executor = new ThreadPoolExecutor(poolSize, poolSize,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
MultipartFile[] files = new MultipartFile[imageUrls.size()];
for (int i = 0; i < imageUrls.size(); i++) {
final int index = i;
executor.submit(() -> {
try {
files[index] = convert(imageUrls.get(index));
} catch (IOException e) {
e.printStackTrace();
}
});
}
executor.shutdown(); // 关闭线程池
// 等待所有任务执行完成
while (!executor.isTerminated()) {
// 等待
}
return files;
}
/**
* 图片地址转换为MultipartFile文件
*
* @param imageUrl
* @return
* @throws IOException
*/
public static MultipartFile convert(String imageUrl) throws IOException {
// 将在线图片地址转换为URL对象
URL url = new URL(imageUrl);
// 打开URL连接 转换为HttpURLConnection对象
URLConnection connection = url.openConnection();
HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
// 获取输入流 并读取输入流中的数据,并保存到字节数组中
InputStream inputStream = httpURLConnection.getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
}
byte[] bytes = byteArrayOutputStream.toByteArray();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
return new MockMultipartFile("file", "filename.jpg", "image/jpeg", byteArrayInputStream);
}
xlsx模板位置

xlsx模板内容

导出内容展示

java-EasyExcel模板导出的更多相关文章
- java根据模板导出PDF详细教程
原文:https://blog.csdn.net/pengyufight/article/details/75305128 题记:由于业务的需要,需要根据模板定制pdf文档,经测试根据模板导出word ...
- Java按模板导出Excel———基于Aspose实现
目录 开发环境 先看效果 引入jar包 校验许可证 导出方法 测试结果 占位符 开发环境 jdk 1.8 Maven 3.6 SpringBoot 2.1.4.RELEASE aspose-cells ...
- Java无模板导出Excel,Apache-POI插件实现
开发环境 jdk 1.8 Maven 3.6 Tomcat 8.5 SpringBoot 2.1.4.RELEASE Apache-POI 3.6 Idea 注意: 我是在现有的基于SpringBoo ...
- java根据模板导出PDF(利用itext)
一.制作模板 1.下载Adobe Acrobat 9 Pro软件(pdf编辑器),制作模板必须使用该工具. 2.下载itextpdf-5.5.5.jar.itext-asian-5.2.0.j ...
- 关于Java中excel表格导出的总结(Java程序导出模板和Java根据模板导出表格两种实现方式)
导出excel通用模板(程序定义模板导出) 转载原文:https://www.jianshu.com/p/5c7b359a159c 如下代码,本方法主要用于程序定义模板格式,并导出文件.该方法将定义和 ...
- Java 根据模板导出PDF
目录 前言 思路一:直接导出pdf 使用itext模板导出pdf 思路二:先导出word再转成pdf 1)导出word 2)word转pdf 最终方案 docx4j spire.doc.free + ...
- java根据模板导出pdf
在网上看了一些Java生成pdf文件的,写的有点乱,有的不支持写入中文字体,有的不支持模板,有的只是随便把数据放里面生成文件,完全不考虑数据怎样放置的以及以后的维护性,想想还是自己总结一个完全版的导出 ...
- java五行代码导出Excel
目录 先看代码 再看效果 EasyExcel 附: Java按模板导出Excel---基于Aspose实现 Java无模板导出Excel,Apache-POI插件实现 已经写过两种Excel导出插件了 ...
- java使用jxls导出Excel
jxls是基于POI的Excel模板导出导入框架.通过使用类似于jstl的标签,有效较少导出Excel的代码量. 1.pom <!-- https://mvnrepository.com/art ...
- java实现excel模板导出
一. 准备工作 1. 点击此下载相关开发工具 2. 将poi-3.8.jxls-core-1.0两个jar包放到工程中,并引用 3. 将excel模板runRecord.xls放到RunRecordB ...
随机推荐
- crontab定时任务不执行的一些原因总结
参考博文地址: https://www.jb51.net/article/154290.htm声明:本文章是在以上地址博文基础上进行整理学习,如有侵权,请联系博主删除,感谢知识共享,一起进步,加油鸭 ...
- iOS发送探针日志到日志系统的简单实现
通过参考Testin的SDK实现方式,我们大致可以确定他们背后的实现方式: 首先,通过加载Testin的SDK,然后收集各种七七八八的数据,再通过socket发送数据到云端. 云端我们已经有了,就是h ...
- 提高 MySQL查询效率的方法
当涉及到提高MySQL查询效率时,以下是一些重要的策略和技巧,可以帮助你优化数据库性能.无论你是一个Web开发者.数据工程师还是系统管理员,这些方法都可以帮助你确保你的MySQL数据库运行得更快.更有 ...
- 升讯威在线客服系统的并发高性能数据处理技术:PLINQ并行查询技术
我在业余时间开发维护了一款免费开源的升讯威在线客服系统,也收获了许多用户.对我来说,只要能获得用户的认可,就是我最大的动力. 最近客服系统成功经受住了客户现场组织的压力测试,获得了客户的认可. 客户组 ...
- Domain Admin域名和SSL证书过期监控到期提醒
基于Python3 + Vue3.js 技术栈实现的域名和SSL证书监测平台 用于解决,不同业务域名SSL证书,申请自不同的平台,到期后不能及时收到通知,导致线上访问异常,被老板责骂的问题 核心功能: ...
- 微信Native支付(扫码支付)商户配置
0.需要从商户平台获取/设置的配置 公众号appId 商户号 APIv3密钥 证书序列号 证书密钥 1.扫码登录商户平台 网址:https://pay.weixin.qq.com/ 2.确认已开通Na ...
- Go 1.22 中的 For 循环
原文在这里. 由 David Chase and Russ Cox 发布于2023年9月19日 Go 1.21 版本包含了对 for 循环作用域的预览更改,我们计划在 Go 1.22 中发布此更改,以 ...
- 开源.NetCore通用工具库Xmtool使用连载 - 扩展动态对象篇
[Github源码] <上一篇> 介绍了Xmtool工具库中的图形验证码类库,今天我们继续为大家介绍其中的扩展动态对象类库. 扩展动态对象是整个工具库中最重要的一个设计.在软件开发过程中, ...
- MySQL PXC 集群运维指南
目录 一.PXC方案概述 二.PXC基础知识 三.PXC节点的配置安装 四.PXC节点的上线与下线 五.其他 一.PXC方案概述 Percona XtraDB Cluster (PXC) 是一个完全开 ...
- Shuffle 题解
Shuffle 题目大意 给定一个长度为 \(n\) 的 01 序列 \(a\),你可以进行至多一次以下操作: 选定 \(a\) 的一个连续段,满足连续段内恰好有 \(k\) 个 \(1\),将该连续 ...