文件批量添加水印和密码合并单元格完整版

news/2024/11/14 11:52:18/

这段代码是一个 Java 方法,用于向文件添加水印和密码。您解释一下:

首先,它接受一个 fileAddress 参数,表示文件的地址。
然后,它创建了一个线程安全的列表 fileDatas,用于存储文件数据。
接下来,它尝试读取文件流,并获取所有 sheet 的数据。
在循环中,它逐个读取每个 sheet 的数据,并将其添加到 fileDatas 列表中。
如果在读取数据时发生异常,它会记录错误并抛出运行时异常。
最后,它生成一个新的文件名 newFileName,并使用 generationFileAddress 方法生成带有水印和密码的文件地址。
请注意,代码中的一些变量(例如 fileUrl、dto)在这里没有定义,您需要根据您的实际情况进行替换。如果您有其他问题或需要更详细的解释,请随时告知!😊

java">	/***文件添加水印密码*/public String fileAddWatermarkPassword(String fileAddress) {final String fileUrl;try {fileUrl = AESUtils.decrypt(fileAddress);} catch (Exception e) {LogUtil.error("报表数据提取", String.format("无法解密文件地址:%s", dto.getFileAddress()), null, e);throw new RuntimeException("无法解密文件地址", e);}List<List<List<String>>> fileDatas = new ArrayList<>();Map<Integer, List<CellRangeAddress>> sheetMergedRegions = new HashMap<>();try (InputStream inputStream = readFileStream(fileUrl);Workbook workbook = WorkbookFactory.create(inputStream)) {FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();for (int i = 0; i < workbook.getNumberOfSheets(); i++) {Sheet sheet = workbook.getSheetAt(i);List<List<String>> fileData = processSheet(sheet,  formulaEvaluator);fileDatas.add(fileData);//捕捉合并区域sheetMergedRegions.put(i, new ArrayList<>(sheet.getMergedRegions()));}} catch (IOException | InvalidFormatException e) {LogUtil.error("报表数据提取", String.format("无法读取文件流, 文件地址:%s", fileUrl), null, e);throw new RuntimeException("无法读取文件流", e);}String newFileName = dto.getDownloadDataType() + ".xlsx";String fileAddress = generationFileAddress(fileDatas, sheetMergedRegions, newFileName, dto.getUseId(), dto.getUseName());return fileAddress;}
java">	/*** 处理合并单元格为空处理*/private List<List<String>> processSheet(Sheet sheet, FormulaEvaluator formulaEvaluator) {List<List<String>> fileData = new ArrayList<>();for (Row row : sheet) {List<String> rowData = new ArrayList<>();// Initialize row with empty strings for missing cellsint lastCellNum = row.getLastCellNum();for (int i = 0; i < lastCellNum; i++) {rowData.add(""); // Default to empty string for all cells}for (Cell cell : row) {int cellIndex = cell.getColumnIndex();String cellValue = getCellValue(cell, formulaEvaluator);rowData.set(cellIndex, cellValue); // Set cell value, handles empty cells}fileData.add(rowData);}return fileData;}
java">	/*** 计算每个单元格的值*/private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#");public static String getCellValue(Cell cell, FormulaEvaluator formulaEvaluator) {if (cell == null) {return "";}switch (cell.getCellType()) {case 1:return cell.getStringCellValue();case 0:if (DateUtil.isCellDateFormatted(cell)) {// Format as date if neededreturn cell.getDateCellValue().toString();} else {// Format numeric valuereturn DECIMAL_FORMAT.format(cell.getNumericCellValue());}case 4:return Boolean.toString(cell.getBooleanCellValue());case 2:// Evaluate formulareturn getCellValue(formulaEvaluator.evaluateInCell(cell), formulaEvaluator);default:return "";}}
java">/*** 生成文件地址* @param data  数据内容* @param fileName  文件名* @param useId 操作者* @return*/public String generationFileAddress(List<List<List<String>>> data, Map<Integer, List<CellRangeAddress>> sheetMergedRegions, String fileName, String useId, String useName) {String randomName = UUID.randomUUID() + "_" + fileName;String fileAddress;File tempFile = null;try (OutputStream outputStream = new FileOutputStream(randomName)) {// 配置水印内容WaterMark watermark = new WaterMark();String content = useName + useId;watermark.setContent(content);watermark.setWidth(400);watermark.setHeight(200);watermark.setYAxis(100);// 创建居中样式WriteCellStyle writeCellStyle = new WriteCellStyle();writeCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);writeCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 创建策略来应用样式WriteCellStyle cellStyle = new WriteCellStyle();cellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);WriteFont writeFont = new WriteFont();cellStyle.setWriteFont(writeFont);HorizontalCellStyleStrategy styleStrategy = new HorizontalCellStyleStrategy(cellStyle, cellStyle);// 使用 EasyExcel 写入数据ExcelWriter excelWriter = EasyExcel.write(outputStream).inMemory(true).registerWriteHandler(new WaterMarkHandler(watermark)).registerWriteHandler(styleStrategy) // 全局居中.build();for (int i = 0; i < data.size(); i++) {List<List<String>> sheetData = data.get(i);excelWriter.write(sheetData, EasyExcel.writerSheet("Sheet" + (i + 1)).build());}excelWriter.finish();} catch (Exception e) {LogUtil.error("文件添加水印和加密", String.format("生成文件地址, 文件名:%s, 操作者:%s", fileName, useId), null, e);throw new RuntimeException("生成并上传带水印的Excel文件时出错", e);}try (FileInputStream fis = new FileInputStream(randomName);Workbook workbook = WorkbookFactory.create(fis);FileOutputStream fos = new FileOutputStream(randomName)) {for (Map.Entry<Integer, List<CellRangeAddress>> entry : sheetMergedRegions.entrySet()) {Sheet sheet = workbook.getSheetAt(entry.getKey());// 设置单元格样式,内容居中CellStyle centeredStyle = workbook.createCellStyle();centeredStyle.setAlignment(HorizontalAlignment.CENTER);centeredStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 重新应用合并单元格并居中for (CellRangeAddress cellRangeAddress : entry.getValue()) {sheet.addMergedRegion(cellRangeAddress);// 对合并单元格的第一个单元格应用居中样式Row row = sheet.getRow(cellRangeAddress.getFirstRow());if (row != null) {Cell cell = row.getCell(cellRangeAddress.getFirstColumn());if (cell != null) {cell.setCellStyle(centeredStyle);}}}// 根据内容自动调整列宽for (int colIndex = 0; colIndex < sheet.getRow(1).getPhysicalNumberOfCells(); colIndex++) {sheet.autoSizeColumn(colIndex);// 设置最大列宽限制,防止列宽过宽int columnWidth = sheet.getColumnWidth(colIndex);int maxColumnWidth = 6000; // 最大列宽sheet.setColumnWidth(colIndex, maxColumnWidth);}}workbook.write(fos);// 加密文件并上传String password = useId + DateUtils.convertDate2Str(new Date(), DateUtils.FORMAT_DATA_COMPACT);FileUtils.encryptExcelFile(randomName, fileName, password);tempFile = new File(fileName);//使用minio 生成文件地址fileAddress = minioUtil.uploadFile(tempFile, "report");} catch (Exception e) {LogUtil.error("文件添加水印和加密", String.format("生成文件地址, 文件名:%s, 操作者:%s", fileName, useId), null, e);throw new RuntimeException("生成并上传带水印的Excel文件时出错", e);} finally {File file = new File(randomName);if(!file.delete()){LogUtil.info("文件添加水印和机密,文件删除失败", String.format("无法删除临时文件:%s", randomName), null);}if (tempFile != null && tempFile.exists()) {if(!tempFile.delete()){LogUtil.info("文件添加水印和机密,文件删除失败", String.format("无法删除临时文件:%s", fileName), null);}}}return fileAddress;}
java">   /**** 从指定的 URL 下载文件并返回 InputStream* @param fileUrl 文件的 URL* @return InputStream 文件输入流* @throws IOException 如果发生网络或 IO 错误*/private InputStream readFileStream(String fileUrl)  {try {// 创建 URL 对象URL url = new URL(fileUrl);// 打开连接并获取输入流URLConnection urlConnection = url.openConnection();InputStream inputStream = new BufferedInputStream(urlConnection.getInputStream());// 返回输入流return inputStream;} catch (IOException e) {LogUtil.error("报表数据提取", String.format("文件地址:%s", fileUrl), null, e);throw new BaseApiException(-1, "文件流读取失败");}}

http://www.ppmy.cn/news/1527068.html

相关文章

ZW3D二次开发_UI_非模板表单_设置表单显示位置

1.ZW3D弹出非模板表单时可以设置弹出位置&#xff08;居中、左下角、右上角等&#xff09; 2.假设已创建好非模板表单 3.在Form属性中添加form_pos属性 4.输入值 base,CTR,0.0 &#xff0c;如下图 也可以设置为其他值显示在不同的位置&#xff0c;如下 5.重新编译&#xff0c;…

使用Jenkins扩展钉钉消息通知

Jenkins借助钉钉插件&#xff0c;实现当构建失败时&#xff0c;自动触发钉钉预警。虽然插件允许自定义消息主体&#xff0c;支持使用 Jenkins环境变量&#xff0c;但是局限性依旧很大。当接收到钉钉通知后&#xff0c;若想进一步查看报错具体原因&#xff0c;仍完全依赖邮件通知…

docker-ce.repo源、kubernetes.repo源

一、docker-ce.repo源 [docker-ce-stable] nameDocker CE Stable - $basearch baseurlhttps://mirrors.aliyun.com/docker-ce/linux/centos/$releasever/$basearch/stable enabled1 gpgcheck1 gpgkeyhttps://mirrors.aliyun.com/docker-ce/linux/centos/gpg [docker-ce-stable-…

优购电商小程序的设计与实现+ssm(lw+演示+源码+运行)

优购电商小程序 摘 要 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和mysql数据库来完成对…

VMware网络配置

在 VMware 中,网络配置至关重要,它决定了虚拟机与物理网络以及其他虚拟机之间的通信方式。VMware 提供了多种网络连接方式,适用于不同的应用场景。以下是 VMware 网络配置的常见类型及其配置方法: 1. VMware 网络类型 VMware 主要提供以下三种网络连接类型: 1.1 桥接网…

【系统架构设计师-2012年真题】案例分析-答案及详解

更多内容请见: 备考系统架构设计师-核心总结索引 文章目录 【材料1】【问题 1】(11 分)【问题 2】(8 分)【问题 3】(6 分)【材料2】【问题 1】(6 分)【问题 2】(9 分)【问题 3】(10 分)【材料3】【问题 1】(共 9 分)【问题 2】(共 16 分)【材料4】【问题 1】(共 10 分)【问题 …

SpringBoot 消息队列RabbitMQ 消息确认机制确保消息发送成功和失败 生产者确认

介绍 有Publisher Confirm(成功)和Publisher Return(失败)两种确认机制。开启确机制认后&#xff0c;在MQ成功收到消息后会返回消息给生产者。 消息投递到了MQ &#xff0c;但是路由失败。此时会通过PublisherReturn返回路由异常原因&#xff0c;然后返回ACK&#xff0c;告知…

C++二叉搜索树学习

目录 一、二叉搜索树概念 二、二叉搜索树的性能分析 三、二叉搜索树的构建 一、二叉搜索树概念 二叉搜索树又叫做二叉排序树&#xff0c;它可以是一颗空树&#xff0c;或者是具有以下性质的二叉树&#xff1a; 若该树的左子树不为空&#xff0c;那么左子树上的任一节点都小…