使用 Java 更新 Word 文档中的图表数据-超详细
使用 Java 更新 Word 文档中的图表数据
在日常的工作中,尤其是在数据分析和报告自动化的场景中,可能会遇到需要定期更新 Word 文档中的图表数据的需求。比如,生成数据报告时,我们需要在图表中更新一些动态的数据值。今天,我将展示如何使用 Java 和 Apache POI 库来实现这一功能:自动读取 Word 文件中的图表,提取 Excel 数据源,修改数据并更新图表。
背景
我们要处理的是 Word 文档中的图表,而这些图表的数据源存储在嵌入的 Excel 文件中。通过操作 Excel 数据,我们可以更新图表中的数据,并且确保图表会根据新的数据重新渲染。
本篇文章的目标是:
- 读取 Word 文件中的图表。
- 提取和修改图表的数据源(嵌入的 Excel 文件)。
- 更新图表数据,并将修改后的数据嵌入回 Word 文件中。
依赖库
本项目使用了 Apache POI 作为核心库,它支持读取和操作 Word 文档(.docx
文件)和 Excel 文件(.xlsx
文件)。你需要在项目中添加以下依赖:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>5.1.1</version>
</dependency>
// 或者 4.0版本
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/ooxml-schemas -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-scratchpad -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
步骤解析
-
读取 Word 文件:
使用XWPFDocument
读取 Word 文件并获取其中的图表对象。每个图表都是一个XWPFChart
对象,其中包含了图表的数据源,即嵌入的 Excel 文件。 -
提取 Excel 数据源:
从图表中提取嵌入的 Excel 数据源,并将其转化为XSSFWorkbook
对象。这样我们可以访问 Excel 文件中的工作表,并对其数据进行修改。 -
修改 Excel 数据:
在修改 Excel 数据时,我们需要根据预设的规则来替换 Excel 单元格中的值。例如,在单元格中,某些值可能是动态的,需要替换为来自其他地方的数据。我们通过字符串查找和替换的方式来完成这一任务。 -
更新图表数据:
修改 Excel 数据后,我们需要将其更新回图表中。通过操作图表的底层 XML,我们可以更新图表的数据引用,并让图表基于新的数据重新绘制。 -
保存并覆盖原文件:
最后,我们将修改后的 Word 文件保存,并覆盖原有的文件,以便生成新的报告。
代码实现
以下是实现这个功能的 Java 代码:
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.xmlbeans.XmlCursor;
import java.io.*;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
public class WordChartUpdater {
static Map<String,Object> cellValueMap = new HashMap<>();
static Map<String, Object> tagDataMap = new HashMap<>();
static {
tagDataMap.put("current_branch_name","测试");
tagDataMap.put("ZYJGZB_079","测试x");
tagDataMap.put("ZYJGZB_091","11");
}
public static void updateChartInWord(File wordFile, ChartData chartData) throws IOException {
// 1. 读取 Word 文件
FileInputStream fis = new FileInputStream(wordFile);
XWPFDocument document = new XWPFDocument(fis);
// 2. 获取文档中的所有图表
List<XWPFChart> charts = document.getCharts();
if (charts.isEmpty()) {
System.out.println("No charts found in the Word document.");
return;
}
// 3. 获取图表的数据源
for (XWPFChart chart : charts) {
XSSFWorkbook workbook = getChartDataAsWorkbook(chart);
if (workbook == null || workbook.getNumberOfSheets() == 0) {
System.out.println("The chart does not have a valid data source.");
continue;
}
// 4. 修改 Excel 数据
modifyChartData(workbook, chartData);
// 5. 将修改后的 Excel 数据嵌入到 Word 图表中
updateChartWithNewData(chart, workbook);
}
// 6. 保存更新后的 Word 文件(覆盖原文件)
FileOutputStream fos = new FileOutputStream(wordFile);
document.write(fos);
fos.close();
fis.close();
}
private static XSSFWorkbook getChartDataAsWorkbook(XWPFChart chart) throws IOException {
try {
return chart.getWorkbook();
} catch (InvalidFormatException e) {
throw new IOException("Failed to extract workbook from chart", e);
}
}
private static void modifyChartData(XSSFWorkbook workbook, ChartData chartData) {
XSSFSheet sheetAt = workbook.getSheetAt(0);
for (int i = 0; i < 20; i++) { // 20列20行数据
XSSFRow row = sheetAt.getRow(i);
if (row == null) {
break;
}
for (int j = 0; j < 20; j++) {
XSSFCell cell = row.getCell(j);
if (cell == null) {
break;
}
if (CellType.NUMERIC != cell.getCellType() && cell.getStringCellValue().contains("$")) {
String key = cell.getStringCellValue();
String substring = key.substring(key.lastIndexOf("$"), key.lastIndexOf("}") + 1);
if (tagDataMap.get(substring) != null) {
String s = key.replace(substring, (String) tagDataMap.get(substring));
cell.setCellValue(s);
cellValueMap.put(cell.getAddress().toString(), s);
} else {
cell.setCellValue(0);
cellValueMap.put(cell.getAddress().toString(), 0);
}
}
}
}
}
private static void updateChartWithNewData(XWPFChart chart, XSSFWorkbook updatedWorkbook) throws IOException {
// 图表数据更新的逻辑...
// 评论或者私信即可领取
}
public static void main(String[] args) throws IOException {
// 创建一个示例对象,填充数据
ChartData chartData = new ChartData("value_079", "Branch A", "value_091");
// 修改 Word 文件
File wordFile = new File("D:\\Desktop\\GZRC_ceshi.docx"); // 修改为你的 Word 文件路径
updateChartInWord(wordFile, chartData);
}
}
代码详解
-
读取 Word 文件:首先,我们使用
XWPFDocument
从 Word 文件中读取数据。 -
提取 Excel 数据源:通过
getChartDataAsWorkbook
获取图表数据源,即嵌入在图表中的 Excel 文件。 -
修改数据:
modifyChartData
方法根据需求修改 Excel 中的单元格数据,使用tagDataMap
中的数据进行替换。 -
更新图表:在
updateChartWithNewData
方法中,我们将修改后的数据更新回图表。 -
保存更新的 Word 文件:最后,通过
document.write(fos)
将修改后的文件保存回磁盘。
总结
使用 Apache POI 处理 Word 文件中的图表更新是一项非常有用的技能,尤其是在自动化报告生成的过程中。通过对图表数据源(嵌入的 Excel 文件)进行修改,我们可以实现动态更新图表数据并更新 Word 文档,从而大大提高工作效率。
如果你有任何问题,或者遇到困难,欢迎在评论区留言。希望这篇文章能对你有所帮助!