如何用Java修改现有XLSX工作簿?求可运行示例及依赖错误解决
解决POI操作Excel时的
SignaturePolicyIdType缺失错误 + 可运行代码示例 我完全懂那种开30个标签页查问题越查越懵的崩溃感!你碰到的无法解析类型org.etsi.uri.x01903.v13.SignaturePolicyIdType错误,本质是缺少了POI处理XAdES数字签名所需的依赖包——虽然你已经加了很多基础POI相关的jar,但签名相关的组件没配齐。
先搞定依赖问题
最省心的方式是替换掉你现有的poi-ooxml-4.0.1.jar,改用poi-ooxml-full-4.0.1.jar,这个包包含了所有OOXML处理所需的依赖(包括签名相关的类),不用再一个个找零散的jar。如果是用Maven构建的话,直接替换依赖:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-full</artifactId> <version>4.0.1</version> </dependency>
如果还是手动加jar,记得把原来的poi-ooxml和poi-ooxml-schemas替换成full版的,避免版本冲突。
可运行的Java示例代码
下面是完整的代码,实现你需要的所有操作:打开现有XLSX、添加命名新工作表、设置列标题、添加多列数据:
import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class ExcelEditor { public static void main(String[] args) { String existingFilePath = "你的现有文件路径.xlsx"; String outputFilePath = "修改后的文件路径.xlsx"; // 可以和原路径相同覆盖,建议先备份原文件 try (FileInputStream fis = new FileInputStream(existingFilePath); Workbook workbook = new XSSFWorkbook(fis); FileOutputStream fos = new FileOutputStream(outputFilePath)) { // 1. 添加并命名新工作表 Sheet newSheet = workbook.createSheet("新数据工作表"); // 2. 设置列标题,添加样式区分 Row headerRow = newSheet.createRow(0); String[] headers = {"ID", "姓名", "部门", "入职日期", "薪资"}; CellStyle headerStyle = workbook.createCellStyle(); Font headerFont = workbook.createFont(); headerFont.setBold(true); headerStyle.setFont(headerFont); for (int i = 0; i < headers.length; i++) { Cell cell = headerRow.createCell(i); cell.setCellValue(headers[i]); cell.setCellStyle(headerStyle); // 自动适配列宽 newSheet.autoSizeColumn(i); } // 3. 添加多行多列数据 Object[][] data = { {1, "张三", "技术部", "2020-05-10", 8500}, {2, "李四", "市场部", "2021-03-15", 7800}, {3, "王五", "人事部", "2019-11-20", 7200} }; for (int rowIndex = 0; rowIndex < data.length; rowIndex++) { Row dataRow = newSheet.createRow(rowIndex + 1); // 从第2行开始(索引1) Object[] rowData = data[rowIndex]; for (int colIndex = 0; colIndex < rowData.length; colIndex++) { Cell cell = dataRow.createCell(colIndex); Object value = rowData[colIndex]; // 根据数据类型设置单元格值 if (value instanceof Integer) { cell.setCellValue((Integer) value); } else if (value instanceof Double) { cell.setCellValue((Double) value); } else { cell.setCellValue(value.toString()); } } } // 4. 保存修改后的文件 workbook.write(fos); System.out.println("Excel文件修改完成!"); } catch (IOException e) { e.printStackTrace(); } } }
小提示
- 运行前记得替换代码里的文件路径,一定要备份原文件,避免意外覆盖。
- 如果用的是POI 4.1.0版本,把依赖版本改成4.1.0即可,代码逻辑完全通用。
- 自动列宽
autoSizeColumn对于中文可能适配不够精准,如果需要更合适的宽度,可以手动设置newSheet.setColumnWidth(i, 256 * 15);(256是POI的宽度单位,15大概对应15个字符宽度)。
内容的提问来源于stack exchange,提问作者Klaus Schuster




