Apache POI+Java:实现Excel工作表追加写入及存在性判断(避免覆盖)
解决Apache POI写入Excel不覆盖原有数据的问题
嗨,我来帮你搞定这个问题~你的代码现在每次都会新建空白工作簿和工作表,直接覆盖了原有文件,而且没处理已有数据的写入位置,所以才会出现删除原有内容、只能写一行的情况。咱们这样调整:
关键修改点
- 读取已有工作簿:不再直接创建新工作簿,先尝试读取现有文件,文件不存在时才新建。
- 复用已有工作表:遍历工作簿中的工作表,找到目标表就复用,找不到再新建。
- 定位空白行:获取已有数据的最后一行索引,从下一行开始写入新数据。
- 正确保存修改:基于读取到的完整工作簿修改后,再写回原文件,保证原有数据不丢失。
修改后的完整代码
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFCell; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class ApachePOIExcelWrite { private static final String FILE_NAME = "c:/viagem.xlsx"; private static final String SHEET_NAME = "Viagem"; public static void main(String[] args) { XSSFWorkbook workbook = null; XSSFSheet sheet = null; try { // 1. 尝试读取已有Excel文件 File excelFile = new File(FILE_NAME); if (excelFile.exists()) { FileInputStream fis = new FileInputStream(excelFile); workbook = new XSSFWorkbook(fis); fis.close(); // 2. 检查目标工作表是否存在 boolean sheetExists = false; for (int i = 0; i < workbook.getNumberOfSheets(); i++) { if (workbook.getSheetName(i).equals(SHEET_NAME)) { sheet = workbook.getSheetAt(i); sheetExists = true; break; } } // 不存在则新建工作表 if (!sheetExists) { sheet = workbook.createSheet(SHEET_NAME); } } else { // 文件不存在时新建工作簿和工作表 workbook = new XSSFWorkbook(); sheet = workbook.createSheet(SHEET_NAME); } // 3. 获取最后一行的索引,下一行就是新数据的起始行 int lastRowNum = sheet.getLastRowNum(); // 如果工作表是空的,lastRowNum是-1,所以起始行设为0 int startRow = lastRowNum == -1 ? 0 : lastRowNum + 1; // 示例数据(可以替换成你的实际数据) Object[][] data = { {"张三", "北京", "2024-05-20"}, {"李四", "上海", "2024-05-21"} }; // 4. 写入数据到新行 for (Object[] rowData : data) { XSSFRow row = sheet.createRow(startRow++); int colNum = 0; for (Object cellData : rowData) { XSSFCell cell = row.createCell(colNum++); if (cellData instanceof String) { cell.setCellValue((String) cellData); } // 可以根据数据类型扩展,比如数字、日期等 } } // 5. 保存修改到文件 FileOutputStream fos = new FileOutputStream(FILE_NAME); workbook.write(fos); fos.close(); System.out.println("数据写入成功,原有内容未被覆盖!"); } catch (IOException e) { e.printStackTrace(); } finally { // 关闭工作簿资源 if (workbook != null) { try { workbook.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
代码说明
- 读取已有文件:通过
FileInputStream读取现有Excel,保证原有数据被加载到工作簿对象中。 - 工作表检查:遍历工作簿的所有工作表,避免重复创建,复用已有工作表。
- 空白行定位:
sheet.getLastRowNum()返回最后一行的索引,空表时返回-1,所以处理后得到新数据的起始行。 - 数据写入:循环写入多行数据,每次创建新行并填充单元格,不会覆盖原有行。
- 资源关闭:在finally块中关闭工作簿,避免资源泄漏。
内容的提问来源于stack exchange,提问作者Paulo Roberto
相关产品推荐
相关产品推荐

