先看效果图:方法都是一样的,所以数据只做了前两组

第一步需要准备模版:
新建一个word插入图表,选择想要的图表。



编辑图表:营业额表示数字,季度表示文字。其他的样式编辑可根据自己的需求更改,这里略过
代码如下:
依赖
<dependencies>
<!--poi-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>jfree</groupId>
<artifactId>jcommon</artifactId>
<version>1.0.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jfree/jfreechart -->
<dependency>
<groupId>jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.13</version>
</dependency>
</dependencies>d
代码:
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
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.util.CellRangeAddress;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xwpf.usermodel.XWPFChart;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PieChart {
public static void main(String[] args) throws Exception {
// 1、创建word文档对象
String filePath = "D:\\words\\cakeshapeword.docx";
String outputUrl = "D:\\output\\cakeshapeword.docx";
List<Map<String, Object>> chartsList = new ArrayList<>();
List<String> keys = new ArrayList<>();
keys.add("一月");
keys.add("二月");
keys.add("三月");
keys.add("四月");
keys.add("五月");
List<Integer> values = new ArrayList<>();
values.add(100);
values.add(150);
values.add(130);
values.add(190);
values.add(200);
chartsList = putMsgToMap(keys,values);
createWord(filePath,outputUrl,chartsList);
}
public static void createWord(String filePath, String outputUrl, List<Map<String, Object>> chartsList) throws IOException, InvalidFormatException {
InputStream is = new FileInputStream(filePath);
XWPFDocument doc = new XWPFDocument(is);
List<XWPFChart> charts = doc.getCharts();
// 获取第一个图
XWPFChart chart0 = charts.get(0);
Workbook wordWb = chart0.getWorkbook();
Sheet wordSheet0 = wordWb.getSheetAt(0);
// 循环数据 赋值
wordSheet0 = extracted(chartsList, wordSheet0);
chart0 = extracted(chart0, chartsList, (XSSFSheet) wordSheet0);
// 获取第二个图,没有做封装,需要的自己处理
XWPFChart chart1 = charts.get(1);
Workbook wordWb1 = chart1.getWorkbook();
Sheet wordSheet1 = wordWb1.getSheetAt(0);
List<String> keys = new ArrayList<>();
keys.add("云大怒");
keys.add("吕布");
keys.add("赵云");
keys.add("典韦");
keys.add("关羽");
List<Integer> values = new ArrayList<>();
values.add(100);
values.add(98);
values.add(96);
values.add(94);
values.add(93);
List<Map<String, Object>> chartsList1 = putMsgToMap(keys,values);
wordSheet1 = extracted(chartsList1, wordSheet1);
chart1 = extracted(chart1, chartsList1, (XSSFSheet) wordSheet1);
// 获取第N个图 此处略过
File outputFile = new File(outputUrl);
try (OutputStream outputStream = new FileOutputStream(outputFile)) {
doc.write(outputStream);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 饼状图循环赋值
* @param chartsList1 数据
* @param wordSheet1 sheet页
* @return
*/
public static Sheet extracted(List<Map<String, Object>> chartsList1, Sheet wordSheet1) {
for (int i = 0; i < chartsList1.size(); i++){
Row row = wordSheet1.getRow(i+1);
if(null != row){
row = wordSheet1.createRow(i+1);
}
Map<String,Object> dataMap = chartsList1.get(i);
for (int y =0;y<dataMap.size();y++){
Cell cell;
if(row.getCell(y) == null){
cell = row.createCell(y);
}else{
cell = row.getCell(y);
}
String key = y == 0 ?"name":"value";
if(key.equals("name")){
cell.setCellValue(dataMap.get(key)+"");
}else {
cell.setCellValue((int)dataMap.get(key));
}
}
}
return wordSheet1;
}
/**
* 刷新饼图数据
* @param chart0
* @param chartsList
* @param wordSheet
* @return
*/
public static XWPFChart extracted(XWPFChart chart0, List<Map<String, Object>> chartsList, XSSFSheet wordSheet) {
// 刷新图表缓存
XDDFChartData chartData = chart0.getChartSeries().get(0);
XDDFChartData.Series series = chartData.getSeries().get(0);
CellRangeAddress nameRangeAddress = new CellRangeAddress(1, chartsList.size(),0,0);
CellRangeAddress valueRangeAddress = new CellRangeAddress(1, chartsList.size(),1,1);
XDDFDataSource lineName = XDDFDataSourcesFactory.fromStringCellRange(wordSheet,nameRangeAddress);
XDDFNumericalDataSource lineVal = XDDFDataSourcesFactory.fromNumericCellRange(wordSheet,valueRangeAddress);
//替换原有的数据
series.replaceData(lineName,lineVal);
chart0.plot(chartData);
return chart0;
}
/**
* 把数值放进 map 里
* @param name
* @param values
* @return
*/
public static List<Map<String,Object>> putMsgToMap(List<String> name,List<Integer> values ){
List<Map<String,Object>> chartsList = new ArrayList<>();
for (int i = 0; i < name.size(); i++) {
Map<String,Object> map = new HashMap();
map.put("name",name.get(i));
map.put("value",values.get(i));
chartsList.add(map);
}
return chartsList;
}
}
注意:如果有多个图表在一起,那么排序的顺序不是你图表在word里的顺序,word有自己的排序,条形第一,面积第二。其他的自行测试看看。我用的是正版微软word。其他的word我没测试过。



















