模板下载路径:https://download.csdn.net/download/junlong750/12805599
package com.mlogcn.wuhan.utils;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xwpf.usermodel.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;
/**
* @author longjun
* @date 2020/8/21 - 16:37
* @description: POI填充word文字和图表
*/
public class WordUtil {
public static void main(String[] args) throws Exception {
// String templatePath = "C:\\Users\\Administrator\\Desktop\\高影响天气模板2.docx";
// InputStream is = new FileInputStream(new File(templatePath))
InputStream is = WordUtil.class.getResourceAsStream("/template/高影响天气模板.docx");
XWPFDocument doc = new XWPFDocument(is);
//模拟统计图数据
//系列
String[] seriesTitles = {"风速(m/s)", "温度(℃)", "湿度(%)"};
//x轴
String[] categories = {"2020-02-20", "2020-02-21", "2020-02-22", "2020-02-23", "2020-02-24", "2020-02-25", "2020-02-26"};
List<Number[]> values = new ArrayList<>();
//风速
Number[] value1 = {17, 15.8, 5, 8.9, 11, 25, 36};
//温度
Number[] value2 = {25.5, 35.5, 28.6, 25.2, 28.9, 38.9, 25.5};
//湿度
Number[] value3 = {100, 50, 80, 70, 80, 65, 80};
values.add(value1);
values.add(value2);
values.add(value3);
XWPFChart xChart = doc.getCharts().get(0);//获取第1个图表
generateChart(xChart, seriesTitles, categories, values, "实况天气折线图");
Map<String, String> data = new HashMap<>();
data.put("${alarmSignal}", "大雾黄色预警信号");
data.put("${alarmPublishTime}", "2020-07-29 03:09:00");
data.put("${alarmPublishContent}", "如东县气象台2020年07月29日03时05分发布大雾黄色预警信号:预计今天早晨我县大部分地区将出现能见度不足500米的雾,能见度较低,请注意防范。");
data.put("${alarmRelieveContent}", "如东县气象台2020年07月29日09时12分解除大雾黄色预警信号。");
changeText(doc, data);
OutputStream os = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\结果文件.docx");
doc.write(os);
close(os);
close(is);
}
/**
* 生成图表
*
* @param chart 从模板中获取到的图表
* @param series 图例
* @param categories X轴
* @param values 数据
* @param chartTitle 图标名称
*/
public static void generateChart(XWPFChart chart, String[] series, String[] categories, List<Number[]> values, String chartTitle) {
List<XDDFChartData> chartSeries = chart.getChartSeries();//不知道这个ChartSeries代表什么意思
//final XDDFLineChartData line = (XDDFLineChartData) data.get(0);//这里一般获取第一个,我们这里是折线图就是XDDFLineChartData
for (XDDFChartData chartData : chartSeries) {
XDDFLineChartData line = (XDDFLineChartData) chartData;
final int numOfPoints = categories.length;
final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
final XDDFDataSource<?> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);
for (int i = 0; i < values.size(); i++) {
final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, i + 1, i + 1));
Number[] value = values.get(i);
final XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(value, valuesDataRange, i + 1);
XDDFChartData.Series ser;//图表中的系列
ser = line.getSeries().get(i);
ser.replaceData(categoriesData, valuesData);
CellReference cellReference = chart.setSheetTitle(series[i], 1);//修改系列标题
ser.setTitle(series[i], cellReference);
}
chart.plot(line);
chart.setTitleText(chartTitle);//折线图标题
chart.setTitleOverlay(false);
}
}
/**
* 替换段落文本
*
* @param document docx解析对象
* @param map 需要替换的信息集合
*/
public static void changeText(XWPFDocument document, Map<String, String> map) {
/**
* 替换段落中的指定文字
*/
Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();
while (itPara.hasNext()) {
XWPFParagraph paragraph = (XWPFParagraph) itPara.next();
Set<String> set = map.keySet();
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
String key = iterator.next();
List<XWPFRun> runList = paragraph.getRuns();
for (int i = 0; i < runList.size(); i++) {
XWPFRun xwpfRun = runList.get(i);
// int fontSize = xwpfRun.getFontSize();//获取原本的字体大小
// String color = xwpfRun.getColor();//获取原本的字体颜色
// String fontFamily = xwpfRun.getFontFamily();//获取原本的字体
String text = xwpfRun.getText(0);
for (Map.Entry<String, String> e : map.entrySet()) {
if (text != null && text.contains(e.getKey())) {
text = text.replace(e.getKey(), e.getValue());
//run.get(i).setText(text,0);
paragraph.removeRun(0);
XWPFRun xWPFRun = paragraph.createRun();
xWPFRun.setText(text, 0);
}
}
}
}
}
/**
* 替换表格中的指定文字
*/
Iterator<XWPFTable> itTable = document.getTablesIterator();
while (itTable.hasNext()) {
XWPFTable table = (XWPFTable) itTable.next();
int count = table.getNumberOfRows();
for (int i = 0; i < count; i++) {
XWPFTableRow row = table.getRow(i);
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
for (Map.Entry<String, String> e : map.entrySet()) {
if (cell.getText().equals(e.getKey())) {
cell.removeParagraph(0);
cell.setText(e.getValue());
}
}
}
}
}
}
/**
* 关闭输入流
*
* @param is
*/
private static void close(InputStream is) {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 关闭输出流
*
* @param os
*/
public static void close(OutputStream os) {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
最终效果