• **项目背景

    随着项目日新月异的变化,对数据的安全性也越来越高,特别是政府类型的项目,数据安全往往是非常重要的,最近项目中导出的文件被要求需要密码才能打开,所以写下这篇文章,特此记录一下。

文章目录

  • 前言
  • 一、文档
  • 二、思考与实现
    • 1.ModelMap方式导出
    • 2.Workbook方式的导出
    • 3.封装导出工具类:
  • 至此,功能已完成

前言

本项目中使用的poi框架为easypoi,springboot版本为2.0.3


提示:以下是本篇文章正文内容,下面案例可供参考

一、文档

easypoi使用教程1.0

二、思考与实现

1.ModelMap方式导出

代码如下(示例):

  List<ExcelExportEntity> entityList = new ArrayList<>();entityList.add(new ExcelExportEntity("乡镇", "town", 15));entityList.add(new ExcelExportEntity("社区", "community", 15));entityList.add(new ExcelExportEntity("姓名", "name", 15));entityList.add(new ExcelExportEntity("手机号", "phone", 15));entityList.add(new ExcelExportEntity("身份证号码", "idcard", 15));entityList.add(new ExcelExportEntity("健康管理措施", "typeName", 15));entityList.add(new ExcelExportEntity("健康管理地址", "addr", 15));entityList.add(new ExcelExportEntity("健康管理开始时间", "startTime", 15));entityList.add(new ExcelExportEntity("健康管理结束时间", "endTime", 15));List<PersonImportant> dataResult = personImportantService.selectExcelList(para);modelMap.put(MapExcelConstants.ENTITY_LIST, entityList);modelMap.put(MapExcelConstants.MAP_LIST, dataResult);modelMap.put(MapExcelConstants.FILE_NAME, "重点人员健康管理人员信息");SessionUser sessionUser = ShiroUtils.getSessionUser();String password = sessionUser.getExcelPassword();if (StringUtils.isEmpty(password)) {password = "123456";}modelMap.put(MapExcelConstants.PASSWORD, password);modelMap.put(NormalExcelConstants.PARAMS, new ExportParams("重点人员健康管理人员信息", "重点人员健康管理人员信息", ExcelType.XSSF));return MapExcelConstants.EASYPOI_MAP_EXCEL_VIEW;

这种方式的导出,我们看到,官方是自带了文档加密功能,只需要我们通过参数的方式传递过去就好了,所以我们不细讲。

2.Workbook方式的导出

代码如下(示例):

@KrtLog("下载导入失败数据")@RequiresPermissions("person:personImportantDetail:excelIn")@GetMapping("person/personImportant/downloadExcelErrorData")public void downloadExcelErrorData(String downErrorDataKey) {List<PersonImportantDetail> dataResult = personImportantService.getExcelErrorData(downErrorDataKey);Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("重点人员健康管理人员信息", "重点人员健康管理人员信息", ExcelType.XSSF), PersonImportantDetail.class, dataResult);ExportExcelUtil.exportExcel(workbook, "导入失败-重点人员健康管理人员信息", response);}

这种方式的导出,查阅了官方文档,没看到官方的加密功能。通过阅读ModelMap方式导出的源码发现了其加密的奥秘:

通过代码我们可以发现:

ModelMap方式的导出最后是会到这个控制层,而通过源码我们可以看到,最终是在这个controller中进行导出的:

那么让我们看看这个里面究竟做了些什么事情吧!继续追踪源码,我们可以发现,具体的实现都是在一个叫out()的方法中进行的:

让我们再次深入其中,为了更好的展现,我把这部分的源码单独粘贴出来了:

 public void out(Workbook workbook, String codedFileName, String password, HttpServletRequest request, HttpServletResponse response) throws Exception {if (workbook instanceof HSSFWorkbook) {codedFileName = codedFileName + ".xls";} else {codedFileName = codedFileName + ".xlsx";}if (password != null && !"".equals(password)) {ByteArrayOutputStream baos = new ByteArrayOutputStream();workbook.write(baos);baos.flush();ByteArrayInputStream workbookInput = new ByteArrayInputStream(baos.toByteArray());EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);Encryptor enc = info.getEncryptor();enc.confirmPassword(password);POIFSFileSystem fs = new POIFSFileSystem();OPCPackage opc = OPCPackage.open(workbookInput);OutputStream os = enc.getDataStream(fs);opc.save(os);os.close();opc.close();baos = new ByteArrayOutputStream();fs.writeFilesystem(baos);baos.flush();response.setHeader("content-disposition", WebFilenameUtils.disposition(codedFileName));byte[] buff = new byte[1024];BufferedInputStream bis = null;try {OutputStream os = response.getOutputStream();bis = new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray()));for(int i = bis.read(buff); i != -1; i = bis.read(buff)) {os.write(buff, 0, buff.length);os.flush();}} catch (IOException var24) {var24.printStackTrace();} finally {if (bis != null) {try {bis.close();} catch (IOException var23) {var23.printStackTrace();}}}} else {response.setHeader("content-disposition", WebFilenameUtils.disposition(codedFileName));ServletOutputStream out = response.getOutputStream();workbook.write(out);out.flush();}}

至此,我们便发现了他的庐山真面目,我们可以参照他的源码,自己写一个导出工具类。

3.封装导出工具类:

package com.krt.common.util;import lombok.extern.slf4j.Slf4j;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.crypt.EncryptionMode;
import org.apache.poi.poifs.crypt.Encryptor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Workbook;import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;/*** @author: lyp* @Date: 2022/1/24 10:38* @Description: excel导出工具类*/
@Slf4j
public class ExportExcelUtil {/*** 导出Excel** @param workbook workbook流* @param fileName 文件名* @param response 响应*/public static void exportExcel(Workbook workbook, String fileName, HttpServletResponse response) {// 输出文件try (OutputStream out = response.getOutputStream()) {// 获取文件名并转码String name = URLEncoder.encode(fileName, "UTF-8");// 编码response.setCharacterEncoding("UTF-8");// 设置强制下载不打开response.setContentType("application/force-download");// 下载文件的默认名称response.setHeader("Content-Disposition", "attachment;filename=" + name + ".xlsx");// 输出表格workbook.write(out);} catch (IOException e) {log.error("文件导出异常,详情如下:{}", e);} finally {try {if (workbook != null) {// 关闭输出流workbook.close();}} catch (IOException e) {log.error("文件导出关闭输出流失败,详情如下:{}", e);}}}/*** 导出一个需要密码打开的Excel** @param workbook workbook流* @param fileName 文件名* @param response 响应*/public static void exportEncryptExcel(Workbook workbook, String fileName, HttpServletResponse response, String password) throws Exception {//if (password != null && !"".equals(password)) {// 文件名fileName = fileName + ".xlsx";// 创建一个字节数组输出流ByteArrayOutputStream workbookOutput = new ByteArrayOutputStream();workbook.write(workbookOutput);workbookOutput.flush();// 创建一个字节数组输入流ByteArrayInputStream workbookInput = new ByteArrayInputStream(workbookOutput.toByteArray());// 加密EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);Encryptor enc = info.getEncryptor();enc.confirmPassword(password);// 创建一个POIFS 文件系统POIFSFileSystem poifsFileSystem = new POIFSFileSystem();OPCPackage opc = OPCPackage.open(workbookInput);OutputStream outputStream = enc.getDataStream(poifsFileSystem);opc.save(outputStream);outputStream.close();opc.close();workbookOutput = new ByteArrayOutputStream();poifsFileSystem.writeFilesystem(workbookOutput);workbookOutput.flush();// 获取文件名并转码String name = URLEncoder.encode(fileName, "UTF-8");// 编码response.setCharacterEncoding("UTF-8");// 设置强制下载不打开response.setContentType("application/force-download");// 下载文件的默认名称response.setHeader("Content-Disposition", "attachment;filename=" + name);byte[] buff = new byte[1024];BufferedInputStream bufferedInputStream = null;try {OutputStream responseOutputStream = response.getOutputStream();bufferedInputStream = new BufferedInputStream(new ByteArrayInputStream(workbookOutput.toByteArray()));for (int i = bufferedInputStream.read(buff); i != -1; i = bufferedInputStream.read(buff)) {responseOutputStream.write(buff, 0, buff.length);responseOutputStream.flush();}} catch (IOException e) {log.error("文件导出失败,详情如下:{}", e);} finally {if (bufferedInputStream != null) {try {bufferedInputStream.close();} catch (IOException e) {log.error("文件导出关闭输出流失败,详情如下:{}", e);}}}}}}

至此,功能已完成

java基于easypoi实现对导出的excel文档加密相关推荐

  1. Java 实现数据库数据 导入 导出成Excel文档的功能

    1.创建导入 导出工具类,写入其导入和导出方法 导出成外部文件: public static ResponseEntity<byte[]> emp2Excel(List<Emp> ...

  2. 如何将Revit明细表导出为Excel文档

    Revit软件没有将明细表直接导出为Excel电子表格的功能,Revit只能将明细表导出为TXT格式,但是这种TXT文件用EXCEL处理软件打开然后另存为XLS格式即可,以Revit2013版自带的建 ...

  3. 支持将数据导出到Excel文档的时候设置单元格格式的.NET控件Spire.DataExport

    Spire.DataExport for .NET是e-iceblue公司推出的一款数据导出类.NET控件.作为一款专业的数据导出控件,Spire.DataExport for .NET可以帮助开发人 ...

  4. 使用NPOI2.0.1.0自定义导出的excel文档数字为文本格式不能公式编辑计算的问题解决

    问题描述: 使用npoi2.0.1.0自定义导出的excel文档为文本格式,在excel中无法直接进行公式计算,不方便使用,需要手工转为数值型才能进行计算. 解决方式: 原先的方式时获取行(Row)进 ...

  5. Excel文档加密网络授权管理方案 - 加密Excel文档并通过服务器端授权管理

    Excel文档加密网络授权管理方案 - 加密Excel文档并通过服务器端授权管理  加密excel文档,支持*.xls;*.csv;*.xlsx等, 保护文档分发,防止编辑.防止复制.防止打印 : 加 ...

  6. Java 通过EasyExcel导出的Excel文档的字体,背景色,自动列宽等符合要求

    这次开任务使用的是EasyExcel导出Excel文档,但是在任务过程中,生成的文档的格式要求并不符合产品和测试的期望值,如图: 想着自己地位低下,也无能力反驳.只好硬着头皮查阅资料来达到他们的想要的 ...

  7. Java使用POI生成柱状图导出到word文档(柱状图)

    本篇文章主要介绍,如何使用Apache POI组件生成柱状图导出到word文档中,具体步骤看下文. 一.实现效果 Java使用POI技术生成柱状图导出到word文档中,最终生成的柱状图如下所示: 二. ...

  8. java后台代码添加超链接_Java 实现Excel文档添加超链接的代码

    超链接即内容链接,通过给特定对象设置超链接,可实现载体与特定网页.文件.邮件.网络等的链接,点击链接载体可打开链接目标,在文档处理中是一种比较常用的功能.本文将介绍通过Java程序给Excel文档添加 ...

  9. [自动化] 前端国际化导出中英文excel文档

    本文是根据自动扫描生成国际化文件后, 叠加的操作, 传送门: 国际化vue-i18n之i18next-scanner自动化使用教程_阿喵阿旺的博客-CSDN博客_i18next vue 然后现在拿到的 ...

最新文章

  1. Android基础教程(四)之-----取得手机屏幕大小DisplayMetrics的应用
  2. Python 学习笔记13 类 - 继承
  3. wxWidgets搜索事件处理函数顺序
  4. 【错误记录】jar 执行错误 ( java.lang.UnsupportedClassVersionError: Unsupported major.minor version 52.0 )
  5. linux关机正确方法
  6. crontab没有正确重定向导致磁盘inode节点空间满
  7. 举个栗子看如何做MySQL 内核深度优化 1
  8. 工具----10、Backtrack的安装
  9. 运放做跟随器有什么要求
  10. 同时买票是怎么实现的_如果是你来构建火车票订票系统,你如何实现?
  11. 【环境配置】Collecting package metadata (current_repodata.json): failed的问题解决
  12. YOLOX论文逐句翻译
  13. 3年试点即将到期,电子印章将成网络货运新动力
  14. jar包扫描工具: gamma
  15. 零基础学习C语言,怎么入门?
  16. tomcat+eclipse +mysql搭建JSP开发环境
  17. qt tablewidget中item添加背景色
  18. Caliburn.Micro学习笔记目录——Zhouyongh
  19. 从公有云到私有云,云原生正在主导数字化转型企业架构
  20. 关于室内分布系统中合路器、功分器、耦合器的对比

热门文章

  1. 安卓和ios的ui设计区别_UI设计中IOS和安卓的设计差异
  2. 使用Route报错:A <Route> is only ever to be used as the child of <Routes> element, never rendered directl
  3. 冒泡排序算法(bubbling sort)
  4. 事件起泡 Event bubbling
  5. Composer中的ThingWorx模型定义—可视化
  6. TweenMax学习小计
  7. win7 eclipse调用虚拟机ubuntu部署的hadoop2.2.0伪分布(1)
  8. Modulo Sum
  9. 我的偶像Micheal.Jackson (MTV全集):本来是有一套Micheal的经典VCD的,但被朋友拿走再没还回来……...
  10. 创业冲突的五种解决方法是_避免创业合伙人之间发生冲突的四种方法