Excel 日期数据自动插入 - Java 代码实现
使用 Java 和 Apache POI 库自动在 Excel 日期数据之间插入中间值
该代码使用 Java 和 Apache POI 库实现自动在 Excel 文件中日期数据之间插入中间值,直到相邻日期间隔小于 10 天。代码包含详细注释,方便理解和使用。
package Data_Recovery;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class EM03 {
public static void main(String[] args) {
try {
// 读取 input-2.xlsx 文件
FileInputStream file = new FileInputStream('input-2.xlsx');
Workbook workbook = new XSSFWorkbook(file);
Sheet sheet = workbook.getSheet('P1');
// 检查是否存在 P2 工作表,如果存在则删除
if (workbook.getSheet('P2') != null) {
workbook.removeSheetAt(workbook.getSheetIndex('P2'));
}
// 创建新的 P2 工作表
Sheet newSheet = workbook.createSheet('P2');
// 复制 P1 工作表的单元格格式到 P2 工作表
copyCellStyle(sheet, newSheet);
// 获取 P1 工作表第一列的时间日期数据
List<Date> dates = getColumnValues(sheet);
// 进行日期插入操作
List<Date> newDates = insertDates(dates);
// 将插入后的日期写入 P2 工作表
writeColumnValues(newSheet, newDates);
// 保存结果到 input-2.xlsx 文件
FileOutputStream outFile = new FileOutputStream('input-2.xlsx');
workbook.write(outFile);
outFile.close();
System.out.println('操作完成');
} catch (Exception e) {
e.printStackTrace();
}
}
// 复制单元格格式
private static void copyCellStyle(Sheet sourceSheet, Sheet targetSheet) {
for (int rowIndex = 0; rowIndex <= sourceSheet.getLastRowNum(); rowIndex++) {
Row sourceRow = sourceSheet.getRow(rowIndex);
Row targetRow = targetSheet.createRow(rowIndex);
for (int columnIndex = 0; columnIndex < sourceRow.getLastCellNum(); columnIndex++) {
Cell sourceCell = sourceRow.getCell(columnIndex);
Cell targetCell = targetRow.createCell(columnIndex);
if (sourceCell != null) {
CellStyle style = sourceCell.getCellStyle();
targetCell.setCellStyle(style);
}
}
}
}
// 获取指定列的日期数据
private static List<Date> getColumnValues(Sheet sheet) {
List<Date> columnValues = new ArrayList<>();
for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
Row row = sheet.getRow(rowIndex);
if (row != null) {
Cell cell = row.getCell(0);
if (cell != null && cell.getCellType() == CellType.NUMERIC) {
columnValues.add(cell.getDateCellValue());
}
}
}
return columnValues;
}
// 在日期数据中插入中间值,直至相邻日期间隔小于 10 天
private static List<Date> insertDates(List<Date> dates) {
List<Date> newDates = new ArrayList<>(dates);
int originalSize = newDates.size();
int maxSize = originalSize * 2; // 设置插入的日期数量阈值
int insertCount = 0; // 插入计数器
for (int i = 0; i < newDates.size() - 1; i++) {
Date currentDate = newDates.get(i);
Date nextDate = newDates.get(i + 1);
long interval = (nextDate.getTime() - currentDate.getTime()) / (24 * 60 * 60 * 1000);
if (interval > 10) { // 修改条件为大于 10 天
while (interval > 10 && newDates.size() < maxSize && insertCount < 100) { // 修改条件为大于 10 天,并添加日期数量限制条件和插入计数器
Date middleDate = new Date((currentDate.getTime() + nextDate.getTime()) / 2);
if (!newDates.contains(middleDate)) {
newDates.add(i + 1, middleDate);
insertCount++;
}
interval = (nextDate.getTime() - middleDate.getTime()) / (24 * 60 * 60 * 1000);
nextDate = newDates.get(i + 2); // 更新相邻日期
}
}
}
return newDates;
}
// 将日期数据写入指定列
private static void writeColumnValues(Sheet sheet, List<Date> dates) {
SimpleDateFormat dateFormat = new SimpleDateFormat('yyyy-MM-dd hh:mm');
for (int rowIndex = 0; rowIndex < dates.size(); rowIndex++) {
Row row = sheet.getRow(rowIndex);
if (row == null) {
row = sheet.createRow(rowIndex);
}
Cell cell = row.createCell(0);
cell.setCellValue(dateFormat.format(dates.get(rowIndex)));
}
}
}
代码说明:
- **读取 Excel 文件:**代码首先读取名为 'input-2.xlsx' 的 Excel 文件,获取 'P1' 工作表。
- **创建新的工作表:**代码创建一个名为 'P2' 的新工作表,并复制 'P1' 工作表的单元格格式到 'P2' 工作表。
- **获取日期数据:**代码获取 'P1' 工作表第一列的日期数据,并存储到
dates列表中。 - **插入中间值:**代码遍历
dates列表,在相邻日期间隔大于 10 天的日期之间插入中间值,并存储到newDates列表中。 - **写入日期数据:**代码将
newDates列表中的日期数据写入 'P2' 工作表第一列。 - **保存结果:**代码将修改后的 Excel 文件保存到 'input-2.xlsx'。
解决程序无限运行的问题:
程序无限运行可能是因为插入日期的条件不满足导致程序陷入死循环。代码中已对插入日期的条件进行修改,并添加了日期数量限制条件和插入计数器,以避免无限插入日期导致程序无法结束。具体修改方法如下:
- **修改插入日期的条件:**将插入日期的条件修改为大于 10 天,即
interval > 10。 - **添加日期数量限制条件和插入计数器:**在插入日期的
while循环中,添加了日期数量限制条件newDates.size() < maxSize和插入计数器insertCount < 100。其中,maxSize设置为原始日期数量的两倍,insertCount初始值为 0,每次成功插入一个日期后,insertCount加 1。
通过以上修改,可以避免无限插入日期导致程序无法结束。
注意事项:
- 该代码假设 Excel 文件中第一列为日期数据,并使用
CellType.NUMERIC来判断单元格类型。如果您的 Excel 文件中的日期数据不在第一列,或者使用其他格式存储日期数据,请根据您的实际情况进行修改。 - 代码中设置的日期数量限制条件和插入计数器只是为了避免程序无限运行,您可以根据实际需求进行调整。
- 请确保您的项目中已添加 Apache POI 库。
希望这份代码和解释能帮助您实现自动在 Excel 日期数据之间插入中间值的功能。如有任何问题,请随时提出。
原文地址: https://www.cveoy.top/t/topic/fTC1 著作权归作者所有。请勿转载和采集!