1.引入easyexcel依赖

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel-core</artifactId><version>3.1.2</version><scope>compile</scope>
</dependency>

2.设置自动列宽,我是获取到导出类上注解设置的宽度

/*** 自动列宽*/
@Component
public class AutoColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {private static final int MAX_COLUMN_WIDTH = 255;//自定义列的列宽private Map<String, Integer> zdyColumnWidth = MapUtils.newHashMapWithExpectedSize(20);private Map<String,Integer> headNameColumnWidthMap = MapUtils.newHashMapWithExpectedSize(20);private final Map<Integer, Map<Integer, Integer>> cache = MapUtils.newHashMapWithExpectedSize(20);@Overrideprotected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell,Head head,Integer relativeRowIndex, Boolean isHead) {boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);if (!needSetWidth) {return;}String cellString = cell.toString();if (zdyColumnWidth.containsKey(cellString)) {writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), zdyColumnWidth.get(cellString) * 256);return;}if (headNameColumnWidthMap.containsKey(cellString)){cell.getCellStyle().setWrapText(true);writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), headNameColumnWidthMap.get(cellString) * 256);return;}if (true) return ;Map<Integer, Integer> maxColumnWidthMap = cache.get(writeSheetHolder.getSheetNo());if (maxColumnWidthMap == null) {maxColumnWidthMap = new HashMap<Integer, Integer>(16);cache.put(writeSheetHolder.getSheetNo(), maxColumnWidthMap);}Integer columnWidth = dataLength(cellDataList, cell, isHead);if (columnWidth < 0) {return;}if (columnWidth > MAX_COLUMN_WIDTH) {columnWidth = MAX_COLUMN_WIDTH;}Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());if (maxColumnWidth == null || columnWidth > maxColumnWidth) {maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256);}}private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {if (isHead) {return cell.getStringCellValue().getBytes().length;}WriteCellData<?> cellData = cellDataList.get(0);CellDataTypeEnum type = cellData.getType();if (type == null) {return -1;}switch (type) {case STRING:return cellData.getStringValue().getBytes().length;case BOOLEAN:return cellData.getBooleanValue().toString().getBytes().length;case NUMBER:return cellData.getNumberValue().toString().getBytes().length;default:return -1;}}public void setZdyColumnWidth(Map<String, Integer> zdyColumnWidth,Map<String,Integer> headNameColumnWidthMap) {this.zdyColumnWidth = zdyColumnWidth;this.headNameColumnWidthMap = headNameColumnWidthMap;}
}

3.将图片导出成超链接的处理类

/*** 动态添加超链接*/
@Component
public class ExcelHyperlinkHandler implements CellWriteHandler {public ExcelHyperlinkHandler() {}@Overridepublic void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,Head head, Integer integer, Integer integer1, Boolean isHead) {}@Overridepublic void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell,Head head, Integer integer, Boolean aBoolean) {}@Overridepublic void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, WriteCellData<?> cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {}@Overridepublic void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {if (isHead) return ;//当前行int curRowIndex = cell.getRowIndex();//当前列int curColIndex = cell.getColumnIndex();CellStyle cellStyle = cell.getCellStyle();// 设置换行cellStyle.setWrapText(true);if (curColIndex == 6 || curColIndex == 7 || curColIndex == 8) {// 设置字体颜色XSSFFont xssfFont = new XSSFFont();xssfFont.setColor(IndexedColors.BLUE.index);cellStyle.setFont(xssfFont);String stringCellValue = cell.getCellType()==CellType.STRING ? cell.getStringCellValue():null;if (StringUtils.isNotBlank(stringCellValue)){//获得超链接,当前单元格的内容就是一个超链接CreationHelper creationHelper = writeSheetHolder.getSheet().getWorkbook().getCreationHelper();Hyperlink hyperlink = creationHelper.createHyperlink(HyperlinkType.URL);String[] picUrlArr = stringCellValue.split(",");// 处理图片超链接if (curColIndex == 6){hyperlink.setAddress(picUrlArr[0]);cell.setHyperlink(hyperlink);//添加超链接cell.setCellValue("图片1");} else if (curColIndex == 7){if (picUrlArr.length > 1){hyperlink.setAddress(picUrlArr[1]);cell.setHyperlink(hyperlink);//添加超链接cell.setCellValue("图片2");}else{cell.setCellValue("");}} else if(curColIndex == 8){if (picUrlArr.length > 2){hyperlink.setAddress(picUrlArr[2]);cell.setHyperlink(hyperlink);//添加超链接cell.setCellValue("图片3");}else{cell.setCellValue("");}}}}}

4.设置表格头和内容样式

/*EasyExcel 表格样式工具类
*/
@Component
public class SetCellStyle extends AbstractVerticalCellStyleStrategy {//表格头样式@Overrideprotected WriteCellStyle headCellStyle(Head head) {WriteCellStyle writeCellStyle = new WriteCellStyle();writeCellStyle.setWrapped(true);WriteFont font = new WriteFont();//自定义字体颜色, 默认黑色font.setColor(IndexedColors.BLACK.index);writeCellStyle.setWriteFont(font);return writeCellStyle;}//单元格格内样式 写法与上面类似@Overrideprotected WriteCellStyle contentCellStyle(Head head) {WriteCellStyle writeCellStyle = new WriteCellStyle();WriteFont font = new WriteFont();Integer columnIndex = head.getColumnIndex();//自定义字体颜色, 默认黑色if (columnIndex == 6 || columnIndex == 7 || columnIndex == 8){font.setColor(IndexedColors.BLUE.index);}else{font.setColor(IndexedColors.BLACK.index);}writeCellStyle.setWriteFont(font);writeCellStyle.setWrapped(true);return writeCellStyle;}public static HorizontalCellStyleStrategy getHorizontalStyleStrategy(){// 头的策略WriteCellStyle headWriteCellStyle = new WriteCellStyle();
//        // 背景设置为灰色
//        headWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_ORANGE.getIndex());
//        WriteFont headWriteFont = new WriteFont();
//        headWriteFont.setFontHeightInPoints((short)10);
//        // 字体样式
//        headWriteFont.setFontName("Frozen");
//        headWriteFont.setColor(IndexedColors.BLUE.getIndex());
//        headWriteCellStyle.setWriteFont(headWriteFont);
//        //自动换行
//        headWriteCellStyle.setWrapped(true);
//        // 水平对齐方式
//        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
//        // 垂直对齐方式
//        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 内容的策略WriteCellStyle contentWriteCellStyle = new WriteCellStyle();contentWriteCellStyle.setWrapped(true);
//        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
//        //        contentWriteCellStyle.setFillPatternType(FillPatternType.SQUARES);
//        // 背景白色
//        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
//        // 字体样式
//        WriteFont contentWriteFont = new WriteFont();
//        // 字体大小
//        contentWriteFont.setFontHeightInPoints((short)10);
//        // 字体样式
//        contentWriteFont.setFontName("Calibri");
//        contentWriteFont.setColor(IndexedColors.BLACK.getIndex());
//        contentWriteCellStyle.setWriteFont(contentWriteFont);
//        // 设置边框
//        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
//        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
//        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
//        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);}}

5.将图片导出在单元格

/*** 生成有图片的excel* @param dataList 数据列表*/
public void generateImageExcel(HttpServletResponse response,List<ReportQuestionReplyExportDTO> dataList) throws Exception {if (CollectionUtils.isEmpty(dataList)) return ;String fileName = "数据列表";String sheetName = "数据列表";String picHeadName = "截图";//图片列最大图片数AtomicReference<Integer> maxImageSize = new AtomicReference<>(0);dataList.forEach(item -> {String picUrls = item.getReportPicUrl();if (StringUtils.isNotEmpty(picUrls)){if (picUrls.split(",").length > maxImageSize.get()) {maxImageSize.set(picUrls.split(",").length);}}});// 表头名称和列宽的映射Map<String, Integer> stringIntegerMap = HandleObjDataUtil.headNameColumnWidthMap(ReportQuestionReplyExportDTO.class);//设置列长度所用类AutoColumnWidthStyleStrategy longWidth = new AutoColumnWidthStyleStrategy();Integer partitionSize = dataList.size()/10;// 对集合切割分区并发处理List<List<ReportQuestionReplyExportDTO>> dataPartition = Lists.partition(dataList, partitionSize > 20? 20 : partitionSize);dataPartition.parallelStream().forEach(objList -> {objList.forEach(item -> {WriteCellData<Void> writeCellData = new WriteCellData<>();if (StringUtils.isNotEmpty(item.getReportPicUrl())) {//每张图片间距Integer splitWidth = -2;//每张图片的长度Integer imageWidth = 60;//图片列的最大长度Integer sumWidth = maxImageSize.get() * (imageWidth + splitWidth);List<ImageData> imageDataList = new ArrayList<>();List<String> imagePathList = Lists.newArrayList(item.getReportPicUrl().split(","));for (int i = 1; i <= imagePathList.size(); i++) {String path = imagePathList.get(i - 1);Integer left = imageWidth * (i - 1) + i * splitWidth;Integer right = sumWidth - imageWidth - left;ImageData imageData = new ImageData();byte[] bytes = null;InputStream inputStream = null;ByteArrayOutputStream outputStream = null;try {inputStream = new URL(path).openStream();outputStream = new ByteArrayOutputStream();// 对图片进行压缩Thumbnails.of(inputStream).scale(0.9f).outputQuality(0.3f).toOutputStream(outputStream);bytes = outputStream.toByteArray();} catch (IOException e) {e.printStackTrace();continue;} finally {if (inputStream != null){try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}}if (bytes.length < 1) continue;imageData.setImage(bytes);imageData.setImageType(ImageData.ImageType.PICTURE_TYPE_PNG);//距离单元格顶部距离imageData.setTop(1);//距离单元格底部距离imageData.setBottom(1);//距离单元格左边距离imageData.setLeft(left);//距离单元格右边距离imageData.setRight(right);imageData.setAnchorType(ClientAnchorData.AnchorType.MOVE_AND_RESIZE);imageDataList.add(imageData);}writeCellData.setImageDataList(imageDataList);Map<String, Integer> zdyColumnWidth = new HashMap<>();//图片列名称,对应导出对象的列名称,图片列长度zdyColumnWidth.put(picHeadName, sumWidth / 6);//设置列长度所用类longWidth.setZdyColumnWidth(zdyColumnWidth,stringIntegerMap);}item.setWriteCellDataFile(writeCellData);});});ResponseDataUtils.setExcelRespProp(response,fileName);EasyExcel.write(response.getOutputStream()).registerWriteHandler(longWidth).head(ReportQuestionReplyExportDTO.class).excelType(ExcelTypeEnum.XLSX).sheet(sheetName).doWrite(dataList);
}

最后由于导出图片太多的话,很慢,导致导出超时,并且excel很大,最后方案改成将图片链接导成excel超链接

easyexcel一个单元格导出多张图片等相关推荐

  1. EasyExcel一单元格导出多图片

    这里导出excel需要使用阿里的EasyExcel组件,项目需要引入EasyExcel依赖,版本可自己选择,博主这里使用2.2.7版本 <dependency><groupId> ...

  2. EasyExcel 实现单元格数据下拉选

    EasyExcel 实现单元格数据下拉选 前言 easyExcel导出模板的时候,固定的某个列我们有固定的是选项值的时候,我们需要将excel的单元格做成下拉选的情况:满足实际的业务需求. 实现 1. ...

  3. 关于使用EasyExcel进行单元格合并的问题

    关于使用EasyExcel进行单元格合并的问题 1.项目场景: 简介:报销单导出要根据指定的excel模板去自动替换对应,然后重新生成一份新的excel.在给定的excel模板中,有部分字段进行了单元 ...

  4. 基于注解和EasyExcel指定单元格下拉选内容

    基于注解和EasyExcel指定单元格下拉选内容 1.场景描述 要求基于EasyExcel进行导出,有的单元格的内容必须是通过下拉选内容进行编辑,以便于后续修改导入,规避用户随意录入数据. 2.编写测 ...

  5. EasyExcel合并单元格策略样例

    EasyExcel合并单元格策略样例 运行示例 处理前: 处理后: 说明 本次使用的是一次性绝对合并策略: List<OnceAbsoluteMergeStrategy> mergeStr ...

  6. EasyExcel合并单元格,通过注解方式实现自定义合并策略

    EasyExcel合并单元格,通过注解方式实现自定义合并策略 简介 今天博主探讨如何实现EasyExcel自定义实现单元格合并策略,考虑需要抽象代码.适用于更多的业务场景,提供了两个工具类,参考过很多 ...

  7. POI easyExcel 设置单元格时间格式的有效性验证

    POI && easyExcel 设置单元格时间格式的有效性验证 设置单元格时间格式的有效性验证示例 // 检查的区域 new CellRangeAddressList(-1, -1, ...

  8. 使用EasyExcel 根据单元格数值动态合并单元格

    文章目录 前言 一.实现思路 二.实现步骤 1.拦截策略 2.EasyExcel写操作 前言 使用EasyExcel 根据单元格数值动态合并单元格 开发中遇到一个需求,需要根据Excel表格中单元格的 ...

  9. datagridview java_仅更新datagridview中的一个单元格

    我正在编写一个Watch Window,它从 Serial Port 获取数据,并在 DataGridView 中显示变量info / value . 我有一个 Timer Event ,每隔500毫 ...

  10. ios 获取最后一个cell_关于ios:向UICollectionView的第一个和最后一个单元格添加填充...

    我子类化UICollectionViewFlowLayout以获取具有分页行为的水平UICollectionView. 只要UICollectionViewCell不是最后一个单元格,它就可以很好地工 ...

最新文章

  1. 9.QT-标准对话框
  2. Controller的要求
  3. [转] ios学习--openURL的使用方法
  4. 03-运行时数据区概述及线程
  5. leetcode 341. Flatten Nested List Iterator | 341. 扁平化嵌套列表迭代器(Java)
  6. Java设计模式之策略模式---写的比较有趣,推荐大家看看
  7. 2012三年大专计算机试题医学,计算机原理2012年4月真题(02384)
  8. vmware 蓝屏_网络安全小百科--利用微软CVE 2019-0708漏洞让对方系统蓝屏死机
  9. 透過 OpenNI / NITE 分析人體骨架(下)
  10. linux进入Mysql 的Dos控制台,dos进入mysql的实现方法
  11. 转dmg 到iso。。。
  12. 收银怎样挂单和取单_挂单取单(PC收银)
  13. 鹏业安装算量软件按桥架快速布线
  14. 黑客张福:互联网是黑暗的森林
  15. Python语言程序设计笔记(全)
  16. 十大实用网站推荐(1)
  17. 台积电市值超越腾讯阿里,成为亚洲第一,互联网不香了?
  18. 20150128-堆雪人
  19. 干细胞膜PLGA纳米颗粒|MDA-MB-231乳腺癌细胞膜修饰纳米囊泡|干细胞膜包覆纳米载体
  20. BZOJ4079 [Wf2014]Pachinko

热门文章

  1. 计算机怎么会自动开机,电脑怎么设置为通电就自动开机
  2. 计算机维修培训教材,计算机芯片级维中心(芯片级维修培训教材)b.doc
  3. JDO与Hibernate之比较(转载)
  4. iptables之forward转发
  5. 爬取动态网站阿里巴巴(1688)商家公司名称及联系方式
  6. C++在指定目录生成txt文件
  7. Android软件常用下载地址
  8. 2012第35周国内Android应用下载动态
  9. CF1090H Linearization
  10. win8 修改背景色为绿豆沙颜色