整个工具的代码都在Gitee或者Github地址内

gitee:solomon-parent: 这个项目主要是总结了工作上遇到的问题以及学习一些框架用于整合例如:rabbitMq、reids、Mqtt、S3协议的文件服务器、mongodb、xxl-job、powerjob还有用Docker compose部署各类中间组件。如果大家有什么想要弄成通用组件的,可以给我留言,我可以研究下

github:https://github.com/ZeroNing/solomon-parent

需要引入的JAR包(版本根据自身要求使用,本教程用的版本均为最新)

    <dependency><groupId>cn.idev.excel</groupId><artifactId>fastexcel</artifactId></dependency>

1.新增对List数组的Converter转换器

public class ListExcelConverter implements Converter<List<?>> {@Overridepublic Class<?> supportJavaTypeKey() {return List.class;}@Overridepublic WriteCellData<?> convertToExcelData(List<?> list, ExcelContentProperty contentProperty,GlobalConfiguration globalConfiguration) throws IOException {if (ValidateUtils.isEmpty(list)){return new WriteCellData<>("");}Object value = list.getFirst();boolean isInputStream = value instanceof InputStream;try {if(isInputStream){List<ImageData> imageDataList = new ArrayList<>();WriteCellData<?> writeCellData = new WriteCellData<>();for(Object val : list){InputStream inputStream = (InputStream) val;ImageData imageData = new ImageData();imageData.setImage(IoUtils.toByteArray(inputStream));imageDataList.add(imageData);}writeCellData.setType(CellDataTypeEnum.EMPTY);writeCellData.setImageDataList(imageDataList);return writeCellData;} else {List<String> stringList = new ArrayList<>();for(Object val : list){stringList.add(val.toString());}return new WriteCellData<>(stringList.toString());}}catch (Exception e){return new WriteCellData<>("InputStream异常");} finally {if (ValidateUtils.isNotEmpty(list) && isInputStream){for(Object val : list){InputStream inputStream = (InputStream) val;inputStream.close();}}}}
}

2.新增对图片的excel处理类

public class ImageCellWriteHandler implements CellWriteHandler {private final HashMap<String, List<ImageData>> imageDataMap = new HashMap<>(16);/*** 单元格的图片最大张数(每列的单元格图片张数不确定,单元格宽度需按照张数最多的长度来设置)*/private final AtomicReference<Integer> MAX_IMAGE_SIZE = new AtomicReference<>(0);/*** 默认图片宽度(单位像素):60*/private final static int DEFAULT_IMAGE_WIDTH = 60;/*** 默认像素转换因子:32*/private final static int DEFAULT_PIXEL_CONVERSION_FACTOR = 32;/*** 图片宽度,单位像素*/private final int imageWidth;/*** 像素转换因子*/private final int pixelConversionFactor;public ImageCellWriteHandler() {this.imageWidth = DEFAULT_IMAGE_WIDTH;this.pixelConversionFactor = DEFAULT_PIXEL_CONVERSION_FACTOR;}public ImageCellWriteHandler(int imageWidth, int pixelConversionFactor) {this.imageWidth = imageWidth;this.pixelConversionFactor = pixelConversionFactor;}@Overridepublic void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, WriteCellData<?> cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {//  在数据转换成功后 不是头就把类型设置成空if (isHead) {return;}//将要插入图片的单元格的type设置为空,下面再填充图片if (ValidateUtils.isNotEmpty(cellData.getImageDataList())) {imageDataMap.put(cell.getRowIndex() + "_" + cell.getColumnIndex(), cellData.getImageDataList());cellData.setType(CellDataTypeEnum.EMPTY);cellData.setImageDataList(new ArrayList<>());}}@Overridepublic void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {//  在单元格写入完毕后 ,自己填充图片if (isHead || ValidateUtils.isEmpty(cellDataList)) {return;}Sheet sheet = cell.getSheet();WriteCellData<?> writeCellData = cellDataList.getFirst();CellDataTypeEnum type = writeCellData.getType();if (type != CellDataTypeEnum.EMPTY) {return;}List<ImageData> imageDataList = imageDataMap.get(cell.getRowIndex() + "_" + cell.getColumnIndex());int widthValue =  imageWidth * pixelConversionFactor;sheet.setColumnWidth(cell.getColumnIndex(), widthValue * MAX_IMAGE_SIZE.get() + pixelConversionFactor);int i = 0;for (ImageData imageData : imageDataList) {// 读取文件this.insertImage(sheet, cell, imageData.getImage(), i);i = i + 1;}}/*** 重新插入一个图片** @param sheet       Excel页面* @param cell        表格元素* @param pictureData 图片数据* @param i           图片顺序*/public int insertImage(Sheet sheet, Cell cell, byte[] pictureData, int i) {int picWidth = Units.pixelToEMU(imageWidth);int index = sheet.getWorkbook().addPicture(pictureData, HSSFWorkbook.PICTURE_TYPE_PNG);Drawing<?> drawing = sheet.getDrawingPatriarch();if (drawing == null) {drawing = sheet.createDrawingPatriarch();}CreationHelper helper = sheet.getWorkbook().getCreationHelper();ClientAnchor anchor = helper.createClientAnchor();/** 设置图片坐标* 为了不让图片遮挡单元格的上边框和右边框,故 x1、x2、y1 这几个坐标点均向后移动了一个像素点*/anchor.setDx1(Units.pixelToEMU(1) + picWidth * i);anchor.setDx2(Units.pixelToEMU(1) + picWidth + picWidth * i);anchor.setDy1(Units.pixelToEMU(1));anchor.setDy2(0);//设置图片位置int columnIndex = cell.getColumnIndex();anchor.setCol1(columnIndex);anchor.setCol2(columnIndex);int rowIndex = cell.getRowIndex();anchor.setRow1(rowIndex);anchor.setRow2(rowIndex + 1);anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);drawing.createPicture(anchor, index);return index;}
}

最后需要在将转换器和excel处理器set入FastEasy/EasyExcel内,代码如下

ExcelWriterBuilder excelWriterBuilder = FastExcel.write(os, clazz).registerConverter(new ListExcelConverter()).registerWriteHandler(new ImageCellWriteHandler())

3.测试结果

3.1单行多照片测试

新增测试类

public class Test {@ExcelProperty(value = "abc")private List<InputStream> inputStream;@ExcelProperty(value = "123456")private List<String> abc = List.of("1","2","3","4","5","6","7","8","9");public List<InputStream> getInputStream() {return inputStream;}public void setInputStream(List<InputStream> inputStream) {this.inputStream = inputStream;}public List<String> getAbc() {return abc;}public void setAbc(List<String> abc) {this.abc = abc;}
}
@RestController
public class TestFileController {private final FileServiceInterface fileService;private final Logger logger = LoggerUtils.logger(TestFileController.class);public TestFileController(FileServiceInterface fileService) {this.fileService = fileService;}@PostMapping("/test")public void test(@RequestPart(name = "file") List<MultipartFile> file) throws Exception {String bucketName = "default";//判断桶是否存在
//        boolean bucketExists = fileService.bucketExists(bucketName);
//        logger.info("桶:{}{}",bucketExists,bucketExists ? "已存在" : "不存在");
//        上传文件
//        FileUpload fileUpload = fileService.upload(file,bucketName);
//        分享URL
//        String shareUrl = fileService.share(fileUpload.getFileName(),bucketName,3600L);
//        删除文件
//        fileService.deleteFile(fileUpload.getFileName(),bucketName);
//        删除桶
//        fileService.deleteBucket(bucketName);Test test = new Test();List<InputStream> inputStreams = new ArrayList<>();for(MultipartFile multipartFile: file){inputStreams.add(multipartFile.getInputStream());}test.setInputStream(inputStreams);List<Object> a = new ArrayList<>();a.add(test);fileService.upload(ExcelUtils. export("123.xls","123",Test.class,a),bucketName);
//        return new ResultVO<>("123");
//        return new ResultVO<String>(shareUrl);}
}

测试结果

3.2测试多列单照片

新增测试类

public class Test {@ExcelProperty(value = "abc")private List<InputStream> inputStream;@ExcelProperty(value = "123456")private List<String> abc = List.of("1","2","3","4","5","6","7","8","9");@ExcelProperty(value = "abc2")private List<InputStream> inputStream2;public List<InputStream> getInputStream2() {return inputStream2;}public void setInputStream2(List<InputStream> inputStream2) {this.inputStream2 = inputStream2;}public List<InputStream> getInputStream() {return inputStream;}public void setInputStream(List<InputStream> inputStream) {this.inputStream = inputStream;}public List<String> getAbc() {return abc;}public void setAbc(List<String> abc) {this.abc = abc;}
}
@RestController
public class TestFileController {private final FileServiceInterface fileService;private final Logger logger = LoggerUtils.logger(TestFileController.class);public TestFileController(FileServiceInterface fileService) {this.fileService = fileService;}@PostMapping("/test")public void test(@RequestPart(name = "file") List<MultipartFile> file) throws Exception {String bucketName = "default";//判断桶是否存在
//        boolean bucketExists = fileService.bucketExists(bucketName);
//        logger.info("桶:{}{}",bucketExists,bucketExists ? "已存在" : "不存在");
//        上传文件
//        FileUpload fileUpload = fileService.upload(file,bucketName);
//        分享URL
//        String shareUrl = fileService.share(fileUpload.getFileName(),bucketName,3600L);
//        删除文件
//        fileService.deleteFile(fileUpload.getFileName(),bucketName);
//        删除桶
//        fileService.deleteBucket(bucketName);Test test = new Test();for(MultipartFile multipartFile: file){List<InputStream> inputStream1 = test.getInputStream();if(ValidateUtils.isEmpty(inputStream1)){inputStream1 = new ArrayList<>();inputStream1.add(multipartFile.getInputStream());test.setInputStream(inputStream1);} else {List<InputStream> inputStream2 = test.getInputStream2();if(ValidateUtils.isEmpty(inputStream2)){inputStream2 = new ArrayList<>();inputStream2.add(multipartFile.getInputStream());test.setInputStream2(inputStream2);}}}List<Object> a = new ArrayList<>();a.add(test);fileService.upload(ExcelUtils. export("123.xls","123",Test.class,a),bucketName);
//        return new ResultVO<>("123");
//        return new ResultVO<String>(shareUrl);}
}

测试结果

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/91053.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/91053.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/91053.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络原理--HTTPHTTPS

目录 一、HTTP 1.1 HTTP是什么 1.2 HTTP协议的工作过程 1.3 HTTP协议格式 1.3.1 抓包工具的使用 1.3.2 抓包结果 1.4 HTTP请求 1.4.1 URL 1.4.2 认识“方法” (method) 1.4.3 认识请求“报头”(header) 1.4.4 认识请求“正文”(body) 1.5 HTTP 响应详解 1.5.1 HTTP…

『 C++ 入门到放弃 』- 哈希表

一、哈希的概念 哈希&#xff0c;也称「 散列 」是一种用来进行高效查找的数据结构&#xff0c;查找的时间复杂度平均为O(1)&#xff0c;其本质就是依赖哈希函数这个算法来将 key 和该 key 存储位置建立一个映射关系。 而因为是有着映射关系&#xff0c;所以哈希的事件复杂度为…

零售收银系统开源代码全解析:连锁门店一体化解决方案(含POS+进销存+商城)

过去10年&#xff0c;收银系统技术经历了从单机版到云服务、从单纯结算到全渠道整合的快速演进。面对连锁多门店、AI称重、智能分账、跨店库存同步等新需求&#xff0c;很多企业的现有传统saas系统已显乏力。本文将梳理收银系统关键技术指标&#xff0c;助您在系统升级时做出明…

能源高效利用如何实现?楼宇自控系统智能化监管建筑设备

随着全球能源危机日益严峻和“双碳”目标的持续推进&#xff0c;建筑领域作为能耗大户&#xff08;约占社会总能耗的40%&#xff09;&#xff0c;其节能潜力备受关注。楼宇自控系统&#xff08;Building Automation System&#xff0c;简称BAS&#xff09;作为建筑智能化的核心…

校园二手交易小程序的设计与实现

文章目录前言详细视频演示具体实现截图后端框架SpringBoot微信小程序持久层框架MyBaits成功系统案例&#xff1a;参考代码数据库源码获取前言 博主介绍:CSDN特邀作者、985高校计算机专业毕业、现任某互联网大厂高级全栈开发工程师、Gitee/掘金/华为云/阿里云/GitHub等平台持续…

Redis(二):Redis高级特性和应用(慢查询、Pipeline、事务)

Redis的慢查询 许多存储系统&#xff08;例如 MySQL)提供慢查询日志帮助开发和运维人员定位系统存在的慢操作。所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间&#xff0c;当超过预设阀值,就将这条命令的相关信息&#xff08;例如:发生时间&#xff0c;耗时&…

如何为你的WordPress网站选择合适的安全插件

在管理WordPress网站时&#xff0c;安全因素至关重要。由于WordPress的广泛使用&#xff0c;它也成为了黑客攻击的首要目标。为了避免潜在的安全风险&#xff0c;选择合适的安全插件至关重要。而Wordfence和iThemes&#xff0c;作为两款颇具人气的WordPress安全插件&#xff0c…

我们使用Rust开发的AI知识库应用

这段时间陆陆续续的开发了2个AI知识库应用&#xff0c;一个面向企业&#xff0c;一个面向C端用户。 飞树智库&#xff1a;一个安全高效的面向 企业的知识库平台&#xff08;https://fskb.coderbox.cn/&#xff09;。 小飞树&#xff1a;一个专注于个人知识管理的AI应用&#…

自动化测试实战篇

目录 1. 自动化实施步骤 1.1 编写web测试用例 1.2 自动化测试脚本开发 1.3 将自动化测试补充至测试报告 1. 自动化实施步骤 1.1 编写web测试用例 1.2 自动化测试脚本开发 TestDevelopment: 测试用例 - Gitee.comhttps://gitee.com/Axurea/test-development/tree/master/2…

idea 服务器Debug端口启动设置

一&#xff1a;在阿里云服务器安全组已经设置了端口授权对象&#xff1a;正确命令&#xff1a;nohup java -Xdebug -Xrunjdwp:transportdt_socket,servery,suspendn,address9998 -jar -Duser.timezoneGMT08 -Xms256m -Xmx256m /opt/projects/*/*/*-starter-1.0-SNAPSHOT.jar -…

大模型量化004

Bert P-tuning BertPET、BertP-Tuning Chain of Thought Few shot Cot Auto-COT 解决手动编写高质量CoT示例麻烦耗时的问题 Auto COT 自动思维链生成器 1.业务场景&#xff1a; 每天收到很多反馈&#xff0c;之前需要人工整理&#xff0c;找到重点&#xff0c;做判断那些需要立…

C#(基本语法)

数据类型C#是一种强类型语言&#xff0c;变量必须声明类型。基本数据类型包括整型&#xff08;int、long&#xff09;、浮点型&#xff08;float、double&#xff09;、布尔型&#xff08;bool&#xff09;、字符型&#xff08;char&#xff09;和字符串型&#xff08;string&a…

ARM-I2C软实现

开发流程引脚初始化引脚功能定义实现读操作实现写操作GD32F4软件I2C初始化void SoftI2C_init() {// 时钟配置rcu_periph_clock_enable(SCL_RCU);// 设置输出模式gpio_mode_set(SCL_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCL_PIN);gpio_output_options_set(SCL_PORT, GPIO_O…

防水医用无人机市场报告:现状、趋势与洞察

市场规模与增长趋势在全球医疗科技快速发展的当下&#xff0c;防水医用无人机市场正崭露头角&#xff0c;展现出强劲的发展势头。据 QYR统计&#xff0c;2023 年全球医用无人机市场销售额达到 1.9 亿美元&#xff0c;预计到 2030 年将飙升至 8.5 亿美元&#xff0c;年复合增长率…

haproxy代理

一.负载均衡 1.1.什么是负载均衡 负载均衡&#xff1a;Load Balance&#xff0c;简称LB&#xff0c;是一种服务或基于硬件设备等实现的高可用反向代理技术&#xff0c;负载均 衡将特定的业务(web服务、网络流量等)分担给指定的一个或多个后端特定的服务器或设备&#xff0c;…

【面试】软件测试面试题

1. 测试用例如何编写 2. bug的生命周期 项目有多少人&#xff1f;多少条测试用例&#xff1f;多少bug&#xff1f;自己发现的第一条&#xff1f;&#xff08;是不是bug&#xff09; 3. 缺陷管理工具 包括Jira, PingCode, 禅道&#xff0c;BugZilla&#xff0c;Redmine, TAPD&am…

HbuilderX开发小程序

1.打卡HbuilderX&#xff0c;选择文件—新建—项目2.创建项目3.在HbuilderX中运行前要确定微信开发这工具的服务端口号是打开的4.HbuilderX中点击预览可以实时预览5.在微信开发者中进行本地测试点击后自动跳转到微信开发者工具中运行项目

Netty中FastThreadLocal解读

io.netty.util.concurrent.FastThreadLocal 是 Netty 中提供的高性能线程局部存储&#xff08;Thread-Local Storage&#xff09;实现&#xff0c;位于 io.netty.util.concurrent 包。它是 Java 标准库 ThreadLocal 的替代品&#xff0c;旨在优化性能&#xff0c;减少内存分配和…

上海迪士尼游玩攻略 小铁寄存柜让你轻松畅玩

去上海迪士尼玩最烦带一堆行李&#xff0c;其实有小铁寄存柜帮忙就能轻装上阵&#xff0c;各个关键位置都有分布&#xff0c;玩起来特别省心。​刚到迪士尼的时候&#xff0c;要是坐地铁到上海国际旅游度假区站&#xff0c;1/2 号口安检区就有小铁柜&#xff0c;行李箱、大背包…

飞算科技重磅出品:飞算 JavaAI 重构 Java 开发效率新标杆

在 Java 开发领域&#xff0c;一款由国家级高新技术企业自主研发的智能工具正引发行业关注 —— 飞算 JavaAI 不仅承载着中国原创技术的创新基因&#xff0c;更以贴合实际开发场景的功能设计&#xff0c;成为众多企业提升 Java 开发效率的核心助力。​作为飞算数智科技&#xf…