直接看代码。根据个人需要做改动

注:POI也可以做批注,文章链接https://www.cnblogs.com/qq1445496485/p/15622664.html

 /**
* 导出(批注)
*
* @param response
*/
@GetMapping("/exportComment")
public void exportComment(HttpServletResponse response)
{
try
{
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
// 设置背景颜色
headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
// 设置头字体
WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontHeightInPoints((short)14);
// 字体加粗
headWriteFont.setBold(true);
headWriteCellStyle.setWriteFont(headWriteFont);
// 设置头居中
headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); // 内容策略
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
// 设置内容字体
WriteFont contentWriteFont = new WriteFont();
contentWriteFont.setFontHeightInPoints((short)12);
contentWriteFont.setFontName("宋体");
contentWriteCellStyle.setWriteFont(contentWriteFont);
// 设置 水平居中
contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
// 设置 垂直居中
contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 设置单元格格式为 文本
contentWriteCellStyle.setDataFormat((short)49); HorizontalCellStyleStrategy horizontalCellStyleStrategy =
new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle); // 生成表格数据
List<List<Object>> dataList = new ArrayList<>();
dataList.add(new ArrayList<>(Arrays.asList(new Object[] {"表头11", "表头2", "表头3", "表头4"})));
dataList.add(new ArrayList<>(Arrays.asList(new Object[] {"表头1", "表头2", "表头3", "表头4"})));
dataList.add(new ArrayList<>(Arrays.asList(new Object[] {"表头31", "表头2", "表头3", "表头4"})));
// 导出文件
String fileName = new String("文件名称.xlsx".getBytes(), "UTF-8");
String sheetName = "模板";
List<Map<String, String>> commentList = new ArrayList<>();
commentList.add(CommentWriteHandler.createCommentMap(sheetName, 0, 0, "A批注。"));
commentList.add(CommentWriteHandler.createCommentMap(sheetName, 0, 1, "B批注。"));
commentList.add(CommentWriteHandler.createCommentMap(sheetName, 2, 0, "B批注。")); response.addHeader("Content-Disposition", "filename=" + fileName);
// 设置类型,扩展名为.xls
response.setContentType("application/vnd.ms-excel");
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
.inMemory(Boolean.TRUE)
.registerWriteHandler(new CommentWriteHandler(commentList, "xlsx"))
.registerWriteHandler(horizontalCellStyleStrategy)
.build();
WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
excelWriter.write(dataList, writeSheet);
// 千万别忘记finish 会帮忙关闭流
excelWriter.finish(); }
catch (Exception e)
{
e.printStackTrace();
}
}

controller

package com.temporary.handle;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.write.handler.AbstractRowWriteHandler;
import com.alibaba.excel.write.metadata.holder.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; /**
* @author Han
* @Description 自定义批注处理器
* @date 2022/3/21
*/
public class CommentWriteHandler extends AbstractRowWriteHandler
{ /**
* sheet名称KEY
*/
public static final String SHEETNAME_NAME = "sheetName"; /**
* 文档后缀名
*/
private String extension; /**
* 列索引key
*/
public static final String COLINDEX_NAME = "colIndex"; /**
* 行索引key
*/
public static final String ROWINDEX_NAME = "rowIndex"; /**
* 批注内容key
*/
public static final String COMMENTCONTENT_NAME = "commentContent"; /**
* sheet页名称列表
*/
private List<String> sheetNameList; List<Map<String, String>> commentList = new ArrayList<>(); public CommentWriteHandler(List<Map<String, String>> commentList, String extension)
{
this.commentList = commentList != null && commentList.size() > 0 ? commentList.stream()
.filter(x -> x.keySet().contains(SHEETNAME_NAME) == true && x.get(SHEETNAME_NAME) != null
&& StrUtil.isNotBlank(x.get(SHEETNAME_NAME).toString()) && x.keySet().contains(COLINDEX_NAME) == true
&& x.get(COLINDEX_NAME) != null && StrUtil.isNotBlank(x.get(COLINDEX_NAME).toString())
&& x.keySet().contains(ROWINDEX_NAME) == true && x.get(ROWINDEX_NAME) != null
&& StrUtil.isNotBlank(x.get(ROWINDEX_NAME).toString())
&& x.keySet().contains(COMMENTCONTENT_NAME) == true && x.get(COMMENTCONTENT_NAME) != null
&& StrUtil.isNotBlank(x.get(COMMENTCONTENT_NAME).toString()))
.collect(Collectors.toList()) : new ArrayList<>();
sheetNameList =
this.commentList.stream().map(x -> x.get(SHEETNAME_NAME).toString()).collect(Collectors.toList());
this.extension = extension;
} /**
* 生成批注信息
*
* @param sheetName sheet页名称
* @param rowIndex 行号
* @param columnIndex 列号
* @param commentContent 批注内容
* @return
*/
public static Map<String, String> createCommentMap(String sheetName, int rowIndex, int columnIndex,
String commentContent)
{
Map<String, String> map = new HashMap<>();
// sheet页名称
map.put(SHEETNAME_NAME, sheetName);
// 行号
map.put(ROWINDEX_NAME, rowIndex + "");
// 列号
map.put(COLINDEX_NAME, columnIndex + "");
// 批注内容
map.put(COMMENTCONTENT_NAME, commentContent);
return map;
} @Override
public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
Integer relativeRowIndex, Boolean isHead)
{
Sheet sheet = writeSheetHolder.getSheet();
// 不需要添加批注,或者当前sheet页不需要添加批注
if (commentList == null || commentList.size() <= 0 || sheetNameList.contains(sheet.getSheetName()) == false)
{
return;
}
// 获取当前行的批注信息
List<Map<String, String>> rowCommentList = commentList.stream()
.filter(x -> StrUtil.equals(x.get(SHEETNAME_NAME).toString(), sheet.getSheetName())
&& relativeRowIndex == Integer.parseInt(x.get(ROWINDEX_NAME)))
.collect(Collectors.toList());
// 当前行没有批注信息
if (rowCommentList == null || rowCommentList.size() <= 0)
{
return;
}
List<String> colIndexList =
rowCommentList.stream().map(x -> x.get(COLINDEX_NAME)).distinct().collect(Collectors.toList());
for (String colIndex : colIndexList)
{
// 同一单元格的批注信息
List<Map<String, String>> cellCommentList = rowCommentList.stream()
.filter(x -> StrUtil.equals(colIndex, x.get(COLINDEX_NAME)))
.collect(Collectors.toList());
if (CollectionUtil.isEmpty(cellCommentList))
{
continue;
}
// 批注内容拼成一条
String commentContent =
cellCommentList.stream().map(x -> x.get(COMMENTCONTENT_NAME)).collect(Collectors.joining());
Cell cell = row.getCell(Integer.parseInt(colIndex));
addComment(cell, commentContent, extension);
}
// 删除批注信息
commentList.remove(rowCommentList);
// 重新获取要添加的sheet页姓名
sheetNameList = commentList.stream().map(x -> x.get(SHEETNAME_NAME).toString()).collect(Collectors.toList());
} /**
* 给Cell添加批注
*
* @param cell 单元格
* @param value 批注内容
* @param extension 扩展名
*/
public static void addComment(Cell cell, String value, String extension)
{
Sheet sheet = cell.getSheet();
cell.removeCellComment();
if ("xls".equals(extension))
{
ClientAnchor anchor = new HSSFClientAnchor();
// 关键修改
anchor.setDx1(0);
anchor.setDx2(0);
anchor.setDy1(0);
anchor.setDy2(0);
anchor.setCol1(cell.getColumnIndex());
anchor.setRow1(cell.getRowIndex());
anchor.setCol2(cell.getColumnIndex() + 5);
anchor.setRow2(cell.getRowIndex() + 6);
// 结束
Drawing drawing = sheet.createDrawingPatriarch();
Comment comment = drawing.createCellComment(anchor);
// 输入批注信息
comment.setString(new HSSFRichTextString(value));
// 将批注添加到单元格对象中
cell.setCellComment(comment);
}
else if ("xlsx".equals(extension))
{
ClientAnchor anchor = new XSSFClientAnchor();
// 关键修改
anchor.setDx1(0);
anchor.setDx2(0);
anchor.setDy1(0);
anchor.setDy2(0);
anchor.setCol1(cell.getColumnIndex());
anchor.setRow1(cell.getRowIndex());
anchor.setCol2(cell.getColumnIndex() + 5);
anchor.setRow2(cell.getRowIndex() + 6);
// 结束
Drawing drawing = sheet.createDrawingPatriarch();
Comment comment = drawing.createCellComment(anchor);
// 输入批注信息
comment.setString(new XSSFRichTextString(value));
// 将批注添加到单元格对象中
cell.setCellComment(comment);
}
} }

Handle

EasyExcel导出添加批注的更多相关文章

  1. NPOI 导出添加批注功能

    这个问题在网上搜,都是说如下即可: //添加批注HSSFPatriarch patr = (HSSFPatriarch)sheet.CreateDrawingPatriarch();HSSFComme ...

  2. EasyExcel导出小结:动态标题、标题格式、相同值合并

    1. 实列相关依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel& ...

  3. easyExcel导出excel的简单使用

    easyExcel导出excel的简单使用 Java解析.生成Excel比较有名的框架有Apache poi.jxl.但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定 ...

  4. office excel中怎么添加批注及修改批注用户名

    office excel中怎么添加批注及修改批注用户名 参考:https://jingyan.baidu.com/article/c33e3f48a52853ea15cbb5db.html 1. of ...

  5. Java 给Word指定字符串添加批注

    本文将介绍在Java程序中如何给Word文档中的指定字符串添加批注.前文中,主要介绍的是针对某个段落来添加批注,以及回复.编辑.删除批注的方法,如果需要针对特定关键词或指定字符串来设置批注,可以参考本 ...

  6. WORD添加批注(JAVA)

    import com.spire.doc.*;import com.spire.doc.documents.CommentMark;import com.spire.doc.documents.Com ...

  7. Activiti添加批注(comment)信息

    在每次提交任务的时候需要描述一些批注信息,例如:请假流程提交的时候要描述信息为什么请假,如果领导驳回可以批注驳回原因等 1.添加批注 // 由于流程用户上下文对象是线程独立的,所以要在需要的位置设置, ...

  8. NOPI Excel插件导入导出 图片批注

    dateTable导出到excel的MemoryStream /// <summary> /// DataTable导出到Excel的MemoryStream Export() /// & ...

  9. SpringBoot基于easyexcel导出和写入Excel

      easyexcel是阿里巴巴旗下开源项目,主要用于Excel文件的导入和导出处理,今天我们利用SpringBoot和easyexcel实战演示如何导出和写入Excel文件. 一.加入我们需要的ea ...

随机推荐

  1. 推荐个我在用的免费翻译软件,支持多家翻译API整合

    前段时间发了个关于<Spring支持PHP>的视频:点击查看 然后有小伙伴留言说:"你这个翻译好像很好用的样子". 的确,我自己也觉得很好用.之前视频没看过的不知道是哪 ...

  2. 【vue】$attrs的作用和使用方法

    之前一直不了解$attrs的作用和使用场景,然后自己翻阅了相关资料整理了下,如有不对的地方请大家指教 $attrs: $attrs是vue版本2.40以上新增的属性: 使用场景: vue项目里面,大家 ...

  3. springmvc-02(配置版与注解版区别)

    首先,我们来看配置版和注解版的相同步骤: 1.新建一个Moudle , springmvc-02-hello , 添加web的支持! 2.确定导入了SpringMVC 的依赖! 3.配置web.xml ...

  4. 攻防世界-MISC:base64÷4

    这是攻防世界高手进阶区的第一题,题目如下: 点击下载附件一,发现是一个文本文档,打开后得到一串字符串 由题意猜测这些字符串应该是base16加密过的,写个脚本跑一下 import base64 s = ...

  5. C#关于在返回值为Task方法中使用Thread.Sleep引发的思考

    起因 最近有个小伙伴提出了一个问题,就是在使用.net core的BackgroundService的时候,对应的ExecuteAsync方法里面写如下代码,会使程序一直卡在当前方法,不会继续执行,代 ...

  6. Mac IntelliJ IDEA插件开发,IDEA Plugin SDK路径

    On Mac, select application icon in /Applications/ 官方文档: Setting Up a Development Environment

  7. Django学习——Django测试环境搭建、单表查询关键字、神奇的双下划线查询(范围查询)、图书管理系统表设计、外键字段操作、跨表查询理论、基于对象的跨表查询、基于双下划线的跨表查询

    Django测试环境搭建 ps: 1.pycharm连接数据库都需要提前下载对应的驱动 2.自带的sqlite3对日期格式数据不敏感 如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3 ...

  8. Intel CPU平台和架构介绍

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 服务器主板上数据传输流依次为CPU .内存.硬盘和网卡, ...

  9. JZ009乘积小于k的子数组

    title: 乘积小于k的子数组 题目描述 题目链接:乘积小于k的子数组.剑指offer009 解题思路 注意: 一开始的乘积k值就是小的,随着右边窗口移动才会不断增大 怎么样的条件才能更新左窗口:当 ...

  10. 安卓导航抽屉 Navigation Drawer 实现沉浸通知栏

    在使用 Navigation Drawer Activity 模版的时候,遇到了通知栏无法完全沉浸的问题,尝试搜索一些现有的解决方法,但是或多或少都会存在一些问题,通过反复尝试找到找到了一种比较靠谱的 ...