3.0版本:https://github.com/asdfLiang/easy-excel-test
2.0版本:https://github.com/asdfLiang/easyexcel-low-test

一、目标效果

  1. 导出一个excel表格,如果单元格中有内容,则进行锁定不允许修改;如果没有,则不锁定允许修改;
  2. 禁止用户复制sheet,防止复制整个sheet到其他excel中进行修改。
    最终效果如下:

    表头和灰色的文字是导出时就有的,不允许修改;4C、5C这两个单元格导出时是空的,允许修改。其他单元格都不允许修改(包括行>5、列>G的单元格)。整个sheet无法选中,也无法进行复制。

二、依赖

    <dependencies><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies>

三、代码实现

测试代码入口

import com.alibaba.excel.EasyExcel;
import excel.CustomSheetWriteHandler;
import excel.StyleWriteHandler;
import org.junit.Test;import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;/*** @author by liangzj* @since 2022/9/17 15:32*/
public class EasyExcelTest {@Testpublic void testWriteExcel() {String pathname = "E:\\liangzj\\Desktop\\test.xlsx";EasyExcel.write(new File(pathname)).head(header()).registerWriteHandler(new StyleWriteHandler()).registerWriteHandler(new CustomSheetWriteHandler()).sheet("Sheet1").doWrite(data());}/*** 数据是先行后列** @return*/public List<List<String>> data() {List<List<String>> data = getRowColMatrix(3, 5);data.get(0).set(0, "用户1");data.get(0).set(1, "1234567890");data.get(0).set(2, "合同1");data.get(0).set(3, "文本1");data.get(0).set(4, "210283202209078615");data.get(1).set(0, "用户2");data.get(1).set(1, "1234553478");data.get(1).set(2, null);data.get(1).set(3, "文本2");data.get(1).set(4, "210211202209073951");data.get(2).set(0, "用户3");data.get(2).set(1, "8332675567");data.get(2).set(2, null);data.get(2).set(3, "文本3");data.get(2).set(4, "120221202209076790");return data;}/*** 表头是先列后行** @return*/public List<List<String>> header() {List<List<String>> header = getColRowMatrix(2, 5);header.get(0).set(0, "姓名");header.get(0).set(1, "姓名");header.get(1).set(0, "手机/邮箱");header.get(1).set(1, "手机/邮箱");header.get(2).set(0, "合同名称");header.get(2).set(1, "合同名称");header.get(3).set(0, "文件1");header.get(3).set(1, "单行文本");header.get(4).set(0, "文件1");header.get(4).set(1, "身份证号");return header;}/*** 生成一个先行后列的矩阵数组** @param maxRow* @param maxCol* @return*/private static List<List<String>> getRowColMatrix(int maxRow, int maxCol) {List<List<String>> header =Stream.generate(() ->Stream.generate(() -> "").limit(maxCol).collect(Collectors.toList())).limit(maxRow).collect(Collectors.toList());return header;}/*** 生成一个先列后行的矩阵数组** @param maxRow* @param maxCol* @return*/private static List<List<String>> getColRowMatrix(int maxRow, int maxCol) {return getRowColMatrix(maxCol, maxRow);}
}

设置保护表格

((SXSSFSheet) writeSheetHolder.getSheet()).lockSelectLockedCells(true);这行代码设置的是"已锁定的单元格不可复制",效果就是别人无法复制整个sheet,这样可以防止别人把内容复制到其他excel表中进行修改。如果允许复制,可以不加,不会影响锁单元格的效果。

package excel;import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.xssf.streaming.SXSSFSheet;/*** @author by liangzj* @since 2022/9/17 16:08*/
public class CustomSheetWriteHandler implements SheetWriteHandler {@Overridepublic void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {// 设置保护密码writeSheetHolder.getSheet().protectSheet("123456");// 锁定单元格不可选中(防止别人直接复制内容到其他excel修改)((SXSSFSheet) writeSheetHolder.getSheet()).lockSelectLockedCells(true);}
}

设置单元格锁定状态

contentStyle和contentStyle2实现的效果是一样的,都是锁指定单元格。contentStyle2方法要注意不能直接cell.getCellStyle().setLocked(true),这么写无法生效。

package excel;import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;/*** 单元格样式处理器** @author by liangzj* @since 2022/9/17 16:26*/
public class StyleWriteHandler extends LongestMatchColumnWidthStyleStrategy {@Overridepublic void afterCellDispose(CellWriteHandlerContext context) {if (context.getHead()) {headerStyle(context);} else {//            contentStyle(context);contentStyle2(context.getCell());}}/*** 表数据格式处理1** @param context*/private void contentStyle(CellWriteHandlerContext context) {// 锁定有内容过的单元格(方法1)WriteCellStyle writeCellStyle = context.getFirstCellData().getOrCreateStyle();writeCellStyle.setLocked(StringUtils.isNotBlank(context.getCell().getStringCellValue()));// 如果锁定,置灰if (writeCellStyle.getLocked()) {WriteFont writeFont = new WriteFont();writeFont.setColor(IndexedColors.GREY_40_PERCENT.index);writeCellStyle.setWriteFont(writeFont);}}/*** 表数据格式处理2** @param cell*/private void contentStyle2(Cell cell) {// 锁定有内容过的单元格(方法2)CellStyle cellStyle = cell.getSheet().getWorkbook().createCellStyle();cellStyle.setLocked(StringUtils.isNotBlank(cell.getStringCellValue()));cell.setCellStyle(cellStyle);// 如果锁定,置灰if (cell.getCellStyle().getLocked()) {Font font = cell.getSheet().getWorkbook().createFont();font.setColor(IndexedColors.GREY_40_PERCENT.index);cellStyle.setFont(font);}}/*** 表头格式处理** @param context*/private static void headerStyle(CellWriteHandlerContext context) {Cell cell = context.getCell();int colWidth = cell.getStringCellValue().length() * 1500;boolean needHidden = "requireId".equals(cell.getStringCellValue());// 根据表头文字设置列宽cell.getSheet().setColumnWidth(cell.getColumnIndex(), colWidth);// 冻结表头cell.getSheet().createFreezePane(1, 2);// 隐藏指定列cell.getSheet().setColumnHidden(cell.getColumnIndex(), needHidden);}
}

2.0版本

如果你用的是2.0版本的EasyExcel,那么写法稍有不同,如下:

package excel;import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;import java.util.List;/*** @author by liangzj* @since 2022/9/17 16:26*/
public class StyleWriteHandler extends LongestMatchColumnWidthStyleStrategy {@Overridepublic void afterCellDispose(WriteSheetHolder writeSheetHolder,WriteTableHolder writeTableHolder,List<CellData> cellDataList,Cell cell,Head head,Integer relativeRowIndex,Boolean isHead) {super.afterCellDispose(writeSheetHolder,writeTableHolder,cellDataList,cell,head,relativeRowIndex,isHead);if (isHead) {headerStyle(cell);} else {contentStyle(cell);}}private void contentStyle(Cell cell) {CellStyle cellStyle = cell.getSheet().getWorkbook().createCellStyle();cellStyle.setLocked(!StringUtils.isEmpty(cell.getStringCellValue()));cell.setCellStyle(cellStyle);if (cell.getCellStyle().getLocked()) {Font font = cell.getSheet().getWorkbook().createFont();font.setColor(IndexedColors.GREY_40_PERCENT.getIndex());cell.getCellStyle().setFont(font);} else {cell.setCellValue("可填写");}}private static void headerStyle(Cell cell) {int colWidth = cell.getStringCellValue().length() * 1500;// 根据表头文字设置列宽cell.getSheet().setColumnWidth(cell.getColumnIndex(), colWidth);// 冻结表头cell.getSheet().createFreezePane(1, 2);}
}

四、总结

点击执行最上方的测试代码,即可在指定位置生成一个excel文件。总结一下,这个实现思路是,先锁定sheet的所有单元格,再在对允许修改单元格进行解锁。实现这个效果的关键点:

  1. 设置保护单元格,没有这个设置,锁定单元格不会生效;
  2. 设置单元格保护状态,注意一定要生成一个新的cellStyle,不要直接cell.getCellStyle().setLocked(true)。

EasyExcel锁定指定单元格 禁止表格复制相关推荐

  1. 怎么wps解除合并单元格_wps表格怎么锁定单元格

    wps表格怎么锁定单元格呢?很多用户对此还不是很清楚,小编这里就给大家带来有关wps表格怎么锁定单元格的回答,希望能够对大家有所帮助. 一.整个表格进行锁定 1.同时按住Ctrl+A,选中整个单元格, ...

  2. html如何取单元格内容,JS获取表格内指定单元格html内容的方法

    JS获取表格内指定单元格html内容的方法 本文实例讲述了JS获取表格内指定单元格html内容的方法.分享给大家供大家参考.具体如下: 下面的代码先通过表格对象的rows获得指定的行的所有单元格数组, ...

  3. excel2019锁定保护指定单元格的方法步骤

    描述:excel2019锁定保护指定单元格的方法步骤 步骤: ctrl+a选择所有表格 右键点击,设置单元格 点击保护,取消勾选保护选项 选择需要锁定保护的区域 右键点击,设置单元格 点击保护 ,勾选 ...

  4. element更改表格表头、行、指定单元格样式

    element更改表格表头.行.指定单元格样式 更改表格的样式 使用header-cell-style属性,可为函数或对象 函数写法 <!-- html --> <el-table ...

  5. easyexcel 无模板写入_给位,问个问题,用easyExcel无模板导出数据时,怎么在指定单元格添加计算公式呢?...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 easyExcel没用过,spire.xls.jar可以给指定单元格添加各种公式 import com.spire.xls.*; public class ...

  6. C#/VB.NET 复制Excel中的指定单元格区域

    本文介绍C#及VB.NET程序代码来复制Excel中的指定单元格区域,包括复制单元格文本及单元格样式.复制时,可在工作簿中的同一个sheet工作表内复制,也可在不同工作簿的不同sheet工作表间复制. ...

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

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

  8. html提取excel指定单元格数据,怎样从很多的表格中提取指定单元格数据

    本帖最后由 11119999hrs 于 2018-7-26 19:24 编辑 For i = 1 To k                                            '遍历 ...

  9. 如何给el-table表格的指定单元格设置颜色

    一.需求及效果图 最近的项目中,遇到给表格中指定单元格设置字体颜色,使用的是el-table做的,控制单元格字体颜色,每一行的最大值设置成绿色,最小值设置成红色,效果如下: 二.方法及代码 使用的是控 ...

最新文章

  1. 前端学习(2323):angular文件介绍
  2. VS 2008中的jQuery Intellisense
  3. 强化学习 —— 资源清单
  4. 设计模式总结 —— 单例设计模式
  5. 空间如何超越极小而存在
  6. WPF界面设计风格资源库
  7. hualinux2.2 环境基础:rpm包安装el6、el7、el8选择
  8. 奶制品生产与销售matlab,奶制品生产和销售
  9. 知名人寿保险品牌SCRM成功案例-全员营销方案赋能 提升客户管理能力
  10. 金融工程及其python应用pdf_金融工程及其Python应用
  11. 算法/最短路径/Bellman-Ford贝尔曼福特算法
  12. web.xml学习随笔
  13. 基于XBee3 zigbee Micropython编程指南
  14. matlab直流电机初始转速,直流电机转速控制的matlab实验.doc
  15. redis数据类型总结
  16. PB中的timer事件
  17. 造价师考试可以用计算机,造价工程师考试带计算器
  18. 【xtku】女星黄美姬win7主题_8.6
  19. C++单继承,多重继承,虚拟继承与内存布局
  20. Python·代码高亮插件YAPF

热门文章

  1. NVME-MI 学习记录_1 框架
  2. office2016 excel关闭受保护的视图
  3. 秃顶和程序员有直接关系?
  4. 这几行最简单的代码 ,却改变了世界
  5. Android GMS (谷歌移动服务)
  6. CDR VBA X6中Exportbitmap函数的用法(导出图片)
  7. CentOS 部署 NodeBB
  8. java 反射 set方法_java 反射调用set方法
  9. 写论文时如何翻译外文文献?
  10. UEStudio快捷键