word导出图表
package com.bjs.glasses.controller.test;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
import java.io.FileOutputStream;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DynamicWordExporter {
public static void exportCombinedReport(String outputPath) {
try (XWPFDocument document = new XWPFDocument()) {
// 添加文档标题
addDocumentTitle(document);
// 添加概述
addOverview(document);
// 添加折线图 - 近视趋势分析
addLineChart(document);
// 添加柱状图 - 各年级近视分布
addBarChart(document);
// 添加饼图 - 近视程度分布
addPieChart(document);
// 添加数据表格
addDataTable(document);
// 添加总结
addConclusion(document);
// 保存文档
try (FileOutputStream fos = new FileOutputStream(outputPath)) {
document.write(fos);
System.out.println("综合视力分析报告导出成功: " + outputPath);
}
} catch (Exception e) {
System.err.println("导出失败: " + e.getMessage());
e.printStackTrace();
}
}
private static void addDocumentTitle(XWPFDocument document) {
// 主标题
XWPFParagraph titlePara = document.createParagraph();
titlePara.setAlignment(ParagraphAlignment.CENTER);
XWPFRun titleRun = titlePara.createRun();
titleRun.setText("学生视力筛查综合分析报告");
titleRun.setBold(true);
titleRun.setFontSize(18);
titleRun.setFontFamily("宋体");
// 副标题
XWPFParagraph subTitlePara = document.createParagraph();
subTitlePara.setAlignment(ParagraphAlignment.CENTER);
XWPFRun subTitleRun = subTitlePara.createRun();
subTitleRun.setText("2024年度视力健康数据分析");
subTitleRun.setFontSize(14);
subTitleRun.setItalic(true);
// 报告日期
XWPFParagraph datePara = document.createParagraph();
datePara.setAlignment(ParagraphAlignment.RIGHT);
XWPFRun dateRun = datePara.createRun();
dateRun.setText("报告生成时间: " + new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
dateRun.setFontSize(10);
dateRun.setColor("666666");
document.createParagraph(); // 空行
}
private static void addOverview(XWPFDocument document) {
XWPFParagraph overviewPara = document.createParagraph();
XWPFRun overviewRun = overviewPara.createRun();
overviewRun.setText("报告概述:");
overviewRun.setBold(true);
overviewRun.setFontSize(12);
XWPFParagraph contentPara = document.createParagraph();
XWPFRun contentRun = contentPara.createRun();
contentRun.setText("本报告基于2022-2024年度全校视力筛查数据,全面分析学生视力状况变化趋势。"
+ "通过折线图展示近视率年度变化,柱状图展示各年级分布情况,饼图展示近视程度构成。"
+ "数据显示近视率呈逐年上升趋势,需加强视力保护措施。");
contentRun.setFontSize(11);
document.createParagraph();
}
private static void addLineChart(XWPFDocument document) {
try {
// 图表标题
addChartTitle(document, "1. 近三年近视趋势分析");
// 创建图表段落
XWPFParagraph chartPara = document.createParagraph();
chartPara.setAlignment(ParagraphAlignment.CENTER);
// 创建chart图表对象
XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);
// 图表相关设置
chart.setTitleText("近三年各年级近视率趋势"); // 图表标题
chart.setTitleOverlay(false); // 图例是否覆盖标题
// 图例设置
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.TOP); // 图例位置
// X轴(分类轴)相关设置
XDDFCategoryAxis xAxis = chart.createCategoryAxis(AxisPosition.BOTTOM); // 创建X轴,并且指定位置
xAxis.setTitle("年份"); // x轴标题
String[] xAxisData = new String[] {"2022", "2023", "2024"};
XDDFCategoryDataSource xAxisSource = XDDFDataSourcesFactory.fromArray(xAxisData); // 设置X轴数据
// Y轴(值轴)相关设置
XDDFValueAxis yAxis = chart.createValueAxis(AxisPosition.LEFT); // 创建Y轴,指定位置
yAxis.setTitle("近视率(%)"); // Y轴标题
yAxis.setMinimum(0.0);
yAxis.setMaximum(50.0);
// 创建折线图对象
XDDFLineChartData lineChart = (XDDFLineChartData) chart.createData(ChartTypes.LINE, xAxis, yAxis);
// 各年级近视率数据
Double[] grade1Data = new Double[]{25.0, 27.5, 29.0}; // 一年级
Double[] grade2Data = new Double[]{28.0, 30.5, 32.0}; // 二年级
Double[] grade3Data = new Double[]{32.5, 35.0, 37.5}; // 三年级
Double[] grade4Data = new Double[]{36.0, 38.5, 41.0}; // 四年级
Double[] grade5Data = new Double[]{40.5, 43.0, 45.5}; // 五年级
Double[] grade6Data = new Double[]{45.0, 47.5, 50.0}; // 六年级
// 加载折线图数据集 - 多个系列
addLineSeries(lineChart, xAxisSource, XDDFDataSourcesFactory.fromArray(grade1Data), "一年级", MarkerStyle.CIRCLE);
addLineSeries(lineChart, xAxisSource, XDDFDataSourcesFactory.fromArray(grade2Data), "二年级", MarkerStyle.SQUARE);
addLineSeries(lineChart, xAxisSource, XDDFDataSourcesFactory.fromArray(grade3Data), "三年级", MarkerStyle.DIAMOND);
addLineSeries(lineChart, xAxisSource, XDDFDataSourcesFactory.fromArray(grade4Data), "四年级", MarkerStyle.TRIANGLE);
addLineSeries(lineChart, xAxisSource, XDDFDataSourcesFactory.fromArray(grade5Data), "五年级", MarkerStyle.STAR);
addLineSeries(lineChart, xAxisSource, XDDFDataSourcesFactory.fromArray(grade6Data), "六年级", MarkerStyle.DOT);
// 绘制折线图
chart.plot(lineChart);
document.createParagraph(); // 空行
} catch (Exception e) {
System.err.println("创建折线图时出错: " + e.getMessage());
addChartPlaceholder(document, "折线图 - 近视趋势分析");
}
}
private static void addBarChart(XWPFDocument document) {
try {
// 图表标题
addChartTitle(document, "2. 各年级近视人数分布");
// 创建图表段落
XWPFParagraph chartPara = document.createParagraph();
chartPara.setAlignment(ParagraphAlignment.CENTER);
// 创建chart图表对象
XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);
// 图表相关设置
chart.setTitleText("2024年各年级近视程度分布"); // 图表标题
chart.setTitleOverlay(false); // 图例是否覆盖标题
// 图例设置
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.TOP); // 图例位置
// X轴(分类轴)相关设置
XDDFCategoryAxis xAxis = chart.createCategoryAxis(AxisPosition.BOTTOM); // 创建X轴,并且指定位置
xAxis.setTitle("年级"); // x轴标题
String[] xAxisData = new String[] {"一年级", "二年级", "三年级", "四年级", "五年级", "六年级"};
XDDFCategoryDataSource xAxisSource = XDDFDataSourcesFactory.fromArray(xAxisData); // 设置X轴数据
// Y轴(值轴)相关设置
XDDFValueAxis yAxis = chart.createValueAxis(AxisPosition.LEFT); // 创建Y轴,指定位置
yAxis.setTitle("人数"); // Y轴标题
yAxis.setCrossBetween(AxisCrossBetween.BETWEEN); // 设置图柱的位置:BETWEEN居中
// 创建柱状图对象
XDDFBarChartData barChart = (XDDFBarChartData) chart.createData(ChartTypes.BAR, xAxis, yAxis);
barChart.setBarDirection(BarDirection.COL); // 设置柱状图的方向:COL竖向
// 各年级不同近视程度数据
Double[] mildData = new Double[]{25.0, 32.0, 45.0, 58.0, 67.0, 75.0}; // 轻度近视
Double[] moderateData = new Double[]{12.0, 18.0, 28.0, 35.0, 42.0, 48.0}; // 中度近视
Double[] highData = new Double[]{5.0, 8.0, 12.0, 18.0, 25.0, 32.0}; // 高度近视
// 加载柱状图数据集 - 多个系列
addBarSeries(barChart, xAxisSource, XDDFDataSourcesFactory.fromArray(mildData), "轻度近视");
addBarSeries(barChart, xAxisSource, XDDFDataSourcesFactory.fromArray(moderateData), "中度近视");
addBarSeries(barChart, xAxisSource, XDDFDataSourcesFactory.fromArray(highData), "高度近视");
// 绘制柱状图
chart.plot(barChart);
document.createParagraph(); // 空行
} catch (Exception e) {
System.err.println("创建柱状图时出错: " + e.getMessage());
addChartPlaceholder(document, "柱状图 - 各年级近视分布");
}
}
private static void addPieChart(XWPFDocument document) {
try {
// 图表标题
addChartTitle(document, "3. 近视程度分布");
// 创建图表段落
XWPFParagraph chartPara = document.createParagraph();
chartPara.setAlignment(ParagraphAlignment.CENTER);
// 创建chart图表对象
XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);
// 图表相关设置
chart.setTitleText("2024年近视程度构成"); // 图表标题
chart.setTitleOverlay(false); // 图例是否覆盖标题
// 图例设置
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.RIGHT); // 图例位置
// 分类数据:饼图中的图例显示
String[] categoryData = new String[] {"正常视力", "轻度近视", "中度近视", "高度近视"};
XDDFCategoryDataSource categorySource = XDDFDataSourcesFactory.fromArray(categoryData);
// 值数据:饼图中的圆形显示
Double[] valueData = new Double[]{642.0, 147.6, 182.4, 99.6};
XDDFNumericalDataSource<Double> valueSource = XDDFDataSourcesFactory.fromArray(valueData);
// 创建饼图对象,饼状图不需要X,Y轴,只需要数据集即可
XDDFPieChartData pieChart = (XDDFPieChartData) chart.createData(ChartTypes.PIE, null, null);
// 加载饼图数据集
XDDFPieChartData.Series pieSeries = (XDDFPieChartData.Series) pieChart.addSeries(categorySource, valueSource);
pieSeries.setTitle("视力分布", null); // 系列提示标题
// 绘制饼图
chart.plot(pieChart);
document.createParagraph(); // 空行
} catch (Exception e) {
System.err.println("创建饼图时出错: " + e.getMessage());
addChartPlaceholder(document, "饼图 - 近视程度分布");
}
}
private static void addDataTable(XWPFDocument document) {
// 表格标题
addChartTitle(document, "4. 详细数据统计");
// 创建表格
XWPFTable table = createTableSafely(document, 7, 7);
// 设置表头
String[] headers = {"年级", "筛查人数", "正常视力", "轻度近视", "中度近视", "高度近视", "近视率%"};
setTableRowSafely(table, 0, headers, true, 10);
// 填充数据
String[][] tableData = {
{"一年级", "200", "158", "25", "12", "5", "21.0%"},
{"二年级", "200", "142", "32", "18", "8", "29.0%"},
{"三年级", "200", "115", "45", "28", "12", "42.5%"},
{"四年级", "200", "89", "58", "35", "18", "55.5%"},
{"五年级", "200", "66", "67", "42", "25", "67.0%"},
{"六年级", "200", "72", "75", "48", "32", "77.5%"}
};
for (int i = 0; i < tableData.length; i++) {
setTableRowSafely(table, i + 1, tableData[i], false, 9);
}
document.createParagraph(); // 空行
}
private static void addConclusion(XWPFDocument document) {
XWPFParagraph conclusionTitle = document.createParagraph();
XWPFRun titleRun = conclusionTitle.createRun();
titleRun.setText("分析与建议:");
titleRun.setBold(true);
titleRun.setFontSize(12);
XWPFParagraph contentPara = document.createParagraph();
XWPFRun contentRun = contentPara.createRun();
contentRun.setText("• 近视率呈逐年上升趋势,高年级学生近视问题尤为突出\n"
+ "• 六年级近视率高达77.5%,需要重点关注和干预\n"
+ "• 高度近视比例随年级升高而增加,需加强早期干预\n"
+ "• 建议加强眼保健操质量监督,确保每天户外活动时间\n"
+ "• 定期开展视力保护健康教育,提高学生和家长重视程度\n"
+ "• 对已近视学生建立视力档案,定期跟踪视力变化情况");
contentRun.setFontSize(11);
}
// 辅助方法:添加折线图系列
private static void addLineSeries(XDDFLineChartData chart, XDDFCategoryDataSource categoryData,
XDDFNumericalDataSource<Double> valueData, String title, MarkerStyle markerStyle) {
XDDFLineChartData.Series series = (XDDFLineChartData.Series) chart.addSeries(categoryData, valueData);
series.setTitle(title, null);
series.setSmooth(false); // 折线
series.setMarkerSize((short) 6); // 标记点大小
series.setMarkerStyle(markerStyle); // 标记点样式
}
// 辅助方法:添加柱状图系列
private static void addBarSeries(XDDFBarChartData chart, XDDFCategoryDataSource categoryData,
XDDFNumericalDataSource<Double> valueData, String title) {
XDDFBarChartData.Series series = (XDDFBarChartData.Series) chart.addSeries(categoryData, valueData);
series.setTitle(title, null);
}
// 辅助方法:添加图表标题
private static void addChartTitle(XWPFDocument document, String title) {
XWPFParagraph titlePara = document.createParagraph();
XWPFRun titleRun = titlePara.createRun();
titleRun.setText(title);
titleRun.setBold(true);
titleRun.setFontSize(12);
document.createParagraph();
}
// 辅助方法:图表占位符
private static void addChartPlaceholder(XWPFDocument document, String chartTitle) {
XWPFParagraph placeholder = document.createParagraph();
placeholder.setAlignment(ParagraphAlignment.CENTER);
XWPFRun run = placeholder.createRun();
run.setText("[" + chartTitle + " - 图表生成失败]");
run.setColor("FF0000");
run.setItalic(true);
document.createParagraph();
}
// 安全创建表格
private static XWPFTable createTableSafely(XWPFDocument document, int rows, int cols) {
XWPFTable table = document.createTable();
// 创建表头行
XWPFTableRow headerRow = table.getRow(0);
if (headerRow == null) {
headerRow = table.createRow();
}
// 确保表头行有足够的单元格
while (headerRow.getTableCells().size() < cols) {
headerRow.addNewTableCell();
}
// 创建数据行
for (int i = 1; i < rows; i++) {
XWPFTableRow dataRow = table.createRow();
while (dataRow.getTableCells().size() < cols) {
dataRow.addNewTableCell();
}
}
// 设置表格宽度
CTTbl ctTbl = table.getCTTbl();
CTTblPr tblPr = ctTbl.getTblPr() == null ? ctTbl.addNewTblPr() : ctTbl.getTblPr();
CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
tblWidth.setType(STTblWidth.DXA);
tblWidth.setW(BigInteger.valueOf(9000));
return table;
}
// 安全设置表格行
private static void setTableRowSafely(XWPFTable table, int rowIndex, String[] data,
boolean isHeader, int fontSize) {
if (table == null || data == null) return;
XWPFTableRow row;
if (rowIndex < table.getNumberOfRows()) {
row = table.getRow(rowIndex);
} else {
row = table.createRow();
}
// 确保行有足够的单元格
while (row.getTableCells().size() < data.length) {
row.addNewTableCell();
}
for (int i = 0; i < data.length && i < row.getTableCells().size(); i++) {
XWPFTableCell cell = row.getCell(i);
if (cell != null) {
setCellContentSafely(cell, data[i], isHeader, fontSize);
}
}
}
// 安全设置单元格内容
private static void setCellContentSafely(XWPFTableCell cell, String text,
boolean isHeader, int fontSize) {
try {
// 清除现有内容
for (int i = cell.getParagraphs().size() - 1; i >= 0; i--) {
cell.removeParagraph(i);
}
// 添加新段落
XWPFParagraph paragraph = cell.addParagraph();
paragraph.setAlignment(ParagraphAlignment.CENTER);
// 创建运行并设置文本
XWPFRun run = paragraph.createRun();
run.setText(text != null ? text : "");
run.setFontSize(fontSize);
if (isHeader) {
run.setBold(true);
}
} catch (Exception e) {
System.err.println("设置单元格内容失败: " + e.getMessage());
try {
cell.setText(text != null ? text : "");
} catch (Exception ex) {
System.err.println("备用设置方法也失败: " + ex.getMessage());
}
}
}
public static void main(String[] args) {
// 导出到指定目录
String outputDir = "D:/视力报告目录";
String fileName = "综合视力分析报告_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".docx";
String outputPath = outputDir + "\\" + fileName;
exportCombinedReport(outputPath);
}
}
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.4</version>
</dependency>
————————————————
版权声明:本文为CSDN博主「zhao_java_drao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhao_java_drao/article/details/124303418
https://www.bilibili.com/opus/608370314915365852
浙公网安备 33010602011771号