Excel 数据填充与折线图生成:KNN 算法及数据补充
// 导入必要的库 package org.example;
import java.io.FileInputStream; // 用于读取输入文件 import java.io.FileOutputStream; // 用于写入输出文件 import java.text.DecimalFormat; // 用于格式化数字 import java.text.ParseException; // 用于解析日期 import java.text.SimpleDateFormat; // 用于格式化日期 import java.util.ArrayList; // 用于存储数据 import java.util.Collections; // 用于排序 import java.util.Comparator; // 用于排序 import java.util.Date; // 用于处理日期 import java.util.HashMap; // 用于存储数据 import java.util.List; // 用于存储数据 import java.util.Map; // 用于存储数据
import org.apache.poi.ss.usermodel.Cell; // Excel 单元格 import org.apache.poi.ss.usermodel.CellType; // Excel 单元格类型 import org.apache.poi.ss.usermodel.Row; // Excel 行 import org.apache.poi.ss.usermodel.Sheet; // Excel 工作表 import org.apache.poi.ss.usermodel.Workbook; // Excel 工作簿 import org.apache.poi.ss.usermodel.WorkbookFactory; // Excel 工作簿工厂 import org.apache.poi.xssf.usermodel.XSSFChart; // Excel 折线图 import org.apache.poi.xssf.usermodel.XSSFChartAxis; // Excel 折线图坐标轴 import org.apache.poi.xssf.usermodel.XSSFChartLegend; // Excel 折线图图例 import org.apache.poi.xssf.usermodel.XSSFClientAnchor; // Excel 折线图锚点 import org.apache.poi.xssf.usermodel.XSSFColor; // Excel 颜色 import org.apache.poi.xssf.usermodel.XSSFDataValidation; // Excel 数据验证 import org.apache.poi.xssf.usermodel.XSSFDataValidationHelper; // Excel 数据验证帮助类 import org.apache.poi.xssf.usermodel.XSSFDataValidationConstraint; // Excel 数据验证约束 import org.apache.poi.xssf.usermodel.XSSFLineChartData; // Excel 折线图数据 import org.apache.poi.xssf.usermodel.XSSFLineChartData.Series; // Excel 折线图数据系列 import org.apache.poi.xssf.usermodel.XSSFRow; // Excel 行 import org.apache.poi.xssf.usermodel.XSSFSheet; // Excel 工作表 import org.apache.poi.xssf.usermodel.XSSFWorkbook; // Excel 工作簿
public class knn {
public static void main(String[] args) {
// 定义输入文件和输出文件的路径
String inputFile = 'input.xlsx';
String outputFile = 'output1.xlsx';
String chartFile = 'chart.xlsx';
try (Workbook workbook = WorkbookFactory.create(new FileInputStream(inputFile)); // 使用工作簿工厂创建 Excel 工作簿
FileOutputStream outputStream = new FileOutputStream(outputFile);
XSSFWorkbook chartWorkbook = new XSSFWorkbook(); // 创建折线图工作簿
FileOutputStream chartOutputStream = new FileOutputStream(chartFile)) { // 创建折线图输出文件
Sheet sheet = workbook.getSheetAt(0); // 获取 Excel 工作表
DecimalFormat df = new DecimalFormat('#.##'); // 创建 Decimal 格式化器,用于保留两位小数
Map<String, List<Double>> dataMap = new HashMap<String, List<Double>>(); // 存储数据
// 对每一行进行处理
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i); // 获取行对象
if (row != null) {
Cell dateCell = row.getCell(0); // 获取日期单元格
Cell valueCell = row.getCell(1); // 获取数值单元格
if (dateCell != null && dateCell.getCellType() == CellType.NUMERIC
&& valueCell != null && valueCell.getCellType() == CellType.NUMERIC) {
Date date = dateCell.getDateCellValue(); // 获取日期
String month = new SimpleDateFormat('yyyy/MM').format(date); // 获取年月
double value = valueCell.getNumericCellValue(); // 获取数值
if (dataMap.containsKey(month)) { // 如果已经存在该月份的数据
dataMap.get(month).add(value); // 将数据添加到列表中
} else {
List<Double> list = new ArrayList<Double>();
list.add(value); // 将数据添加到列表中
dataMap.put(month, list); // 将列表添加到数据中
}
}
}
}
// 对数据进行补充
for (String month : dataMap.keySet()) {
List<Double> list = dataMap.get(month);
if (list.size() < 5) { // 如果数据少于五个
Date date = parseDate(month + '/01 00:00'); // 解析日期
int dayOfWeek = date.getDay(); // 获取星期几
int daysOfMonth = getDaysOfMonth(date); // 获取该月份的天数
int startDay = 1; // 开始日期
int endDay = daysOfMonth; // 结束日期
if (dayOfWeek > 0) { // 如果不是星期日
startDay = 8 - dayOfWeek; // 计算开始日期
}
if (list.size() > 0) { // 如果已经有数据
double lastValue = list.get(list.size() - 1); // 获取最后一个数值
for (int i = startDay; i <= daysOfMonth && list.size() < 5; i++) { // 对每一天进行处理
Date d = parseDate(month + '/' + i + ' 00:00'); // 解析日期
int day = d.getDay(); // 获取星期几
if (day == 0 || day == 6) { // 如果是周末
continue; // 跳过
}
list.add(lastValue); // 将数值添加到列表中
}
} else { // 如果没有数据
for (int i = startDay; i <= daysOfMonth && list.size() < 5; i++) { // 对每一天进行处理
Date d = parseDate(month + '/' + i + ' 00:00'); // 解析日期
int day = d.getDay(); // 获取星期几
if (day == 0 || day == 6) { // 如果是周末
continue; // 跳过
}
list.add(0.0); // 将 0 添加到列表中
}
}
}
}
// 对数据进行排序
List<String> monthList = new ArrayList<String>(dataMap.keySet());
Collections.sort(monthList, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
try {
Date d1 = new SimpleDateFormat('yyyy/MM').parse(o1);
Date d2 = new SimpleDateFormat('yyyy/MM').parse(o2);
return d1.compareTo(d2);
} catch (ParseException e) {
e.printStackTrace();
return 0;
}
}
});
// 将数据写入输出文件
XSSFWorkbook outputWorkbook = new XSSFWorkbook(); // 创建输出工作簿
for (String month : monthList) {
List<Double> list = dataMap.get(month);
if (list.size() >= 5) { // 如果数据大于等于五个
XSSFSheet outputSheet = outputWorkbook.createSheet(month); // 创建工作表
XSSFRow headerRow = outputSheet.createRow(0); // 创建标题行
headerRow.createCell(0).setCellValue('Date'); // 创建日期列
headerRow.createCell(1).setCellValue('Value'); // 创建数值列
int rowIndex = 1; // 行索引
for (int i = 1; i <= list.size(); i++) { // 对每一个数值进行处理
XSSFRow row = outputSheet.createRow(rowIndex++); // 创建行
Date date = parseDate(month + '/' + i + ' 00:00'); // 解析日期
row.createCell(0).setCellValue(date); // 设置日期单元格的值
row.createCell(1).setCellValue(list.get(i - 1)); // 设置数值单元格的值
}
// 创建折线图
XSSFChart chart = chartWorkbook.createChart(); // 创建折线图
XSSFChartLegend legend = chart.getOrCreateLegend(); // 获取或创建图例
legend.setPosition(org.apache.poi.xssf.usermodel.charts.LegendPosition.TOP_RIGHT); // 设置图例位置
XSSFChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(org.apache.poi.xssf.usermodel.charts.AxisPosition.BOTTOM); // 创建底部坐标轴
bottomAxis.setCrosses(AxisCrosses.AUTO_ZERO); // 设置交叉点
XSSFChartAxis leftAxis = chart.getChartAxisFactory().createValueAxis(org.apache.poi.xssf.usermodel.charts.AxisPosition.LEFT); // 创建左侧坐标轴
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO); // 设置交叉点
XSSFLineChartData data = chart.getChartDataFactory().createLineChartData(); // 创建折线图数据
Series series = data.addSeries(bottomAxis.createCategoryDataSource(outputSheet.getColumn(0))); // 添加系列
series.setTitle(outputSheet.getSheetName(), chart.getWorkbook().getCreationHelper().createCellRangeAddress(0, 0, 1, 1)); // 设置系列标题
series.setLineWidth(2); // 设置线宽
series.setMarkerStyle(MarkerStyle.CIRCLE); // 设置标记样式
series.setSmooth(true); // 设置平滑曲线
series.setMarkerSize(6); // 设置标记大小
series.setMarkerColor(new XSSFColor(new java.awt.Color(0, 176, 80))); // 设置标记颜色
chart.plot(data, bottomAxis, leftAxis); // 绘制折线图
// 创建数据验证
XSSFDataValidationHelper validationHelper = new XSSFDataValidationHelper(outputSheet);
XSSFDataValidationConstraint constraint = (XSSFDataValidationConstraint) validationHelper.createFormulaListConstraint('=MONTH($A$2:$A$' + outputSheet.getLastRowNum() + ')');
XSSFDataValidation validation = (XSSFDataValidation) validationHelper.createValidation(constraint, new CellRangeAddressList(1, outputSheet.getLastRowNum(), 0, 0));
validation.createErrorBox('Invalid Month', 'Please select a valid month.');
validation.setShowErrorBox(true);
outputSheet.addValidationData(validation);
}
}
outputWorkbook.write(outputStream); // 将工作簿写入输出文件
chartWorkbook.write(chartOutputStream); // 将折线图工作簿写入输出文件
System.out.println('Data filling and chart creation completed.'); // 输出信息
} catch (Exception e) { // 捕获异常
e.printStackTrace();
}
}
// 计算KNN邻近算法填充的值
private static double calculateKNN(Sheet sheet, int rowIndex, int columnIndex) {
List<Double> data = new ArrayList
原文地址: https://www.cveoy.top/t/topic/f2bt 著作权归作者所有。请勿转载和采集!