Java Excel 数据排序并填充缺失数据:按日期排序并使用均值填充
以下是一个 Java 处理 Excel 按日期排列数据中数据缺失的小程序的示例代码:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
public class ExcelDataSortAndFill {
public static void main(String[] args) throws Exception {
// 读取 Excel 文件
File inputFile = new File('input.xlsx');
FileInputStream inputStream = new FileInputStream(inputFile);
Workbook inputWorkbook = WorkbookFactory.create(inputStream);
Sheet inputSheet = inputWorkbook.getSheetAt(0);
// 按日期排序
List<DataRow> dataRows = readDataRowsFromSheet(inputSheet);
Collections.sort(dataRows);
// 创建新的 Excel 文件
File outputFile = new File('output.xlsx');
FileOutputStream outputStream = new FileOutputStream(outputFile);
Workbook outputWorkbook = WorkbookFactory.create(true);
Sheet outputSheet = outputWorkbook.createSheet();
// 填充数据
fillDataRowsToSheet(dataRows, outputSheet);
// 保存新的 Excel 文件
outputWorkbook.write(outputStream);
outputWorkbook.close();
outputStream.close();
}
private static List<DataRow> readDataRowsFromSheet(Sheet sheet) {
List<DataRow> dataRows = new ArrayList<>();
for (Row row : sheet) {
Cell dateCell = row.getCell(0);
Cell valueCell = row.getCell(1);
if (dateCell == null || dateCell.getCellType() != CellType.NUMERIC
|| valueCell == null || valueCell.getCellType() != CellType.NUMERIC) {
continue;
}
Date date = DateUtil.getJavaDate(dateCell.getNumericCellValue());
double value = valueCell.getNumericCellValue();
dataRows.add(new DataRow(date, value));
}
return dataRows;
}
private static void fillDataRowsToSheet(List<DataRow> dataRows, Sheet sheet) {
if (dataRows.isEmpty()) {
return;
}
// 写入第一行标题
Row headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue('Date');
headerRow.createCell(1).setCellValue('Value');
// 计算均值
double sum = 0.0;
for (DataRow row : dataRows) {
sum += row.value;
}
double mean = sum / dataRows.size();
// 写入数据行
int rowIndex = 1;
SimpleDateFormat dateFormat = new SimpleDateFormat('yyyy-MM-dd');
for (DataRow row : dataRows) {
// 填充缺失数据
while (rowIndex < dataRows.size()) {
DataRow nextRow = dataRows.get(rowIndex);
long days = (nextRow.date.getTime() - row.date.getTime()) / (1000 * 60 * 60 * 24);
if (days > 1) {
for (int i = 1; i < days; i++) {
Row missingRow = sheet.createRow(rowIndex++);
Date missingDate = new Date(row.date.getTime() + i * 24L * 60L * 60L * 1000L);
missingRow.createCell(0).setCellValue(dateFormat.format(missingDate));
missingRow.createCell(1).setCellValue(mean);
}
}
rowIndex++;
row = nextRow;
}
// 写入当前数据行
Row dataRow = sheet.createRow(rowIndex++);
dataRow.createCell(0).setCellValue(dateFormat.format(row.date));
dataRow.createCell(1).setCellValue(row.value);
}
}
private static class DataRow implements Comparable<DataRow> {
public Date date;
public double value;
public DataRow(Date date, double value) {
this.date = date;
this.value = value;
}
@Override
public int compareTo(DataRow o) {
return this.date.compareTo(o.date);
}
}
}
代码解析:
-
读取 Excel 文件:使用
WorkbookFactory.create方法可以根据文件类型自动选择对应的Workbook实现类,并读取 Excel 文件中的数据。 -
按日期排序:将读取的数据行封装为
DataRow对象,实现Comparable接口,然后使用Collections.sort方法按照日期排序。 -
创建新的 Excel 文件:使用
WorkbookFactory.create(true)方法创建一个新的 Excel 文件,其中true参数表示创建一个空白工作簿。 -
填充数据:将排序后的数据行按照日期顺序填充到新的 Excel 文件中,缺失的数据用均值填充代替。具体实现步骤如下:
- 首先在新的 Excel 文件中创建一个工作表,并写入第一行标题。
- 然后计算均值,用于填充缺失数据。
- 遍历排序后的数据行,如果当前行与下一行之间有缺失的日期,则在新的 Excel 文件中填充缺失的数据行,日期用
SimpleDateFormat格式化为字符串,数据用均值填充。 - 最后写入当前的数据行。
-
保存新的 Excel 文件:使用
Workbook.write方法将修改后的工作簿写入到输出流中,然后关闭工作簿和输出流。
注意:该程序依赖于Apache POI库,需要在项目中引入相关的 JAR 文件。
原文地址: https://www.cveoy.top/t/topic/oIud 著作权归作者所有。请勿转载和采集!