本文参考地址:https://blog.csdn.net/u014427811/article/details/100771314
在参考文章的基础上,增加了模板样例
模板样例地址 百度网盘
链接:https://pan.baidu.com/s/16qDvE2-V-tpX_bY8NNnepw
提取码:yhbd
这个必须引入poi4.0以上版本,以验证过
完整pom.xml内容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.4.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.turing</groupId><artifactId>report</artifactId><version>0.0.1-SNAPSHOT</version><name>report</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/org.apache.poi/poi --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.0</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

数据这块完全拷贝大哥的

package com.turing.report.controller;import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlCursor;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @author :MaWT* @date :Created in 2020/2/21 11:40* @description:* @modified By:* @version: $*/
@RestController
public class ReportController {@GetMapping("export")public static void export() throws Exception {final String returnurl = "C:\\Users\\wangcan\\Desktop\\data\\reportTemplate-word.docx";  // 结果文件final String templateurl = "C:\\Users\\wangcan\\Desktop\\templates\\reportTemplate-word.docx";  // 模板文件InputStream is = new FileInputStream(new File(templateurl));XWPFDocument doc = new XWPFDocument(is);// 替换word模板数据replaceAll(doc);// 保存结果文件try {File file = new File(returnurl);if (file.exists()) {file.delete();}FileOutputStream fos = new FileOutputStream(returnurl);doc.write(fos);fos.close();} catch (Exception e) {e.printStackTrace();}}/*** @Description: 替换段落和表格中*/public static void replaceAll(XWPFDocument doc) throws InvalidFormatException, IOException {doParagraphs(doc); // 处理段落文字数据,包括文字和表格、图片doCharts(doc);  // 处理图表数据,柱状图、折线图、饼图啊之类的}/*** 处理段落文字** @param doc* @throws InvalidFormatException* @throws FileNotFoundException* @throws IOException*/public static void doParagraphs(XWPFDocument doc) throws InvalidFormatException, IOException {// 文本数据Map<String, String> textMap = new HashMap<String, String>();textMap.put("var", "我是被替换的文本内容");// 图片数据Map<String, String> imgMap = new HashMap<String, String>();imgMap.put("img", "E:\\idea\\timg.jpg");/**----------------------------处理段落------------------------------------**/List<XWPFParagraph> paragraphList = doc.getParagraphs();if (paragraphList != null && paragraphList.size() > 0) {for (XWPFParagraph paragraph : paragraphList) {List<XWPFRun> runs = paragraph.getRuns();for (XWPFRun run : runs) {String text = run.getText(0);if (text != null) {// 替换文本信息String tempText = text;//   String key = tempText.replaceAll("\\{\\{", "").replaceAll("}}", "");if (!StringUtils.isEmpty(textMap.get(text))) {run.setText(textMap.get(text), 0);}// 替换图片内容 参考:https://blog.csdn.net/a909301740/article/details/84984445String tempImgText = text;//   String imgkey = tempImgText.replaceAll("\\{\\{@", "").replaceAll("}}", "");if (!StringUtils.isEmpty(imgMap.get(text))) {String imgPath = imgMap.get(text);try {run.setText("", 0);run.addPicture(new FileInputStream(imgPath), Document.PICTURE_TYPE_PNG, "img.png", Units.toEMU(200), Units.toEMU(200));} catch (Exception e) {e.printStackTrace();}}// 动态表格if (text.contains("table")) {run.setText("", 0);XmlCursor cursor = paragraph.getCTP().newCursor();XWPFTable tableOne = doc.insertNewTbl(cursor);// ---这个是关键// 设置表格宽度,第一行宽度就可以了,这个值的单位,目前我也还不清楚,还没来得及研究tableOne.setWidth(8500);// 表格第一行,对于每个列,必须使用createCell(),而不是getCell(),因为第一行嘛,肯定是属于创建的,没有create哪里来的get呢XWPFTableRow tableOneRowOne = tableOne.getRow(0);//行PoiWordTools.setWordCellSelfStyle(tableOneRowOne.getCell(0), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "10%", "序号");PoiWordTools.setWordCellSelfStyle(tableOneRowOne.createCell(), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "45%", "公司名称(英文)");PoiWordTools.setWordCellSelfStyle(tableOneRowOne.createCell(), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "45%", "公司名称(中文)");// 表格第二行XWPFTableRow tableOneRowTwo = tableOne.createRow();//行PoiWordTools.setWordCellSelfStyle(tableOneRowTwo.getCell(0), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "10%", "一行一列");PoiWordTools.setWordCellSelfStyle(tableOneRowTwo.getCell(1), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "45%", "一行一列");PoiWordTools.setWordCellSelfStyle(tableOneRowTwo.getCell(2), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "45%", "一行一列");// ....... 可动态添加表格}}}}}}/*** 处理图表** @param doc* @throws FileNotFoundException*/public static void doCharts(XWPFDocument doc) throws FileNotFoundException {/**----------------------------处理图表------------------------------------**/// 数据准备List<String> titleArr = new ArrayList<String>();// 标题titleArr.add("title");titleArr.add("金额");List<String> fldNameArr = new ArrayList<String>();// 字段名fldNameArr.add("item1");fldNameArr.add("item2");// 数据集合List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();// 第一行数据Map<String, String> base1 = new HashMap<String, String>();base1.put("item1", "材料费用");base1.put("item2", "500");// 第二行数据Map<String, String> base2 = new HashMap<String, String>();base2.put("item1", "出差费用");base2.put("item2", "300");// 第三行数据Map<String, String> base3 = new HashMap<String, String>();base3.put("item1", "住宿费用");base3.put("item2", "300");listItemsByType.add(base1);listItemsByType.add(base2);listItemsByType.add(base3);// 获取word模板中的所有图表元素,用map存放// 为什么不用list保存:查看doc.getRelations()的源码可知,源码中使用了hashMap读取文档图表元素,// 对relations变量进行打印后发现,图表顺序和文档中的顺序不一致,也就是说relations的图表顺序不是文档中从上到下的顺序Map<String, POIXMLDocumentPart> chartsMap = new HashMap<String, POIXMLDocumentPart>();//动态刷新图表List<POIXMLDocumentPart> relations = doc.getRelations();for (POIXMLDocumentPart poixmlDocumentPart : relations) {if (poixmlDocumentPart instanceof XWPFChart) {  // 如果是图表元素String str = poixmlDocumentPart.toString();System.out.println("str:" + str);String key = str.replaceAll("Name: ", "").replaceAll(" - Content Type: application/vnd\\.openxmlformats-officedocument\\.drawingml\\.chart\\+xml", "").trim();System.out.println("key:" + key);chartsMap.put(key, poixmlDocumentPart);}}System.out.println("\n图表数量:" + chartsMap.size() + "\n");// 第一个图表-条形图POIXMLDocumentPart poixmlDocumentPart0 = chartsMap.get("/word/charts/chart1.xml");PoiWordTools.replaceBarCharts(poixmlDocumentPart0, titleArr, fldNameArr, listItemsByType);// 第二个-柱状图POIXMLDocumentPart poixmlDocumentPart1 = chartsMap.get("/word/charts/chart2.xml");PoiWordTools.replaceBarCharts(poixmlDocumentPart1, titleArr, fldNameArr, listItemsByType);// 第三个图表-多列柱状图doCharts3(chartsMap);// 第四个图表-折线图doCharts4(chartsMap);// 第五个图表-饼图POIXMLDocumentPart poixmlDocumentPart4 = chartsMap.get("/word/charts/chart5.xml");PoiWordTools.replacePieCharts(poixmlDocumentPart4, titleArr, fldNameArr, listItemsByType);doCharts6(chartsMap);}public static void doCharts3(Map<String, POIXMLDocumentPart> chartsMap) {// 数据准备List<String> titleArr = new ArrayList<String>();// 标题titleArr.add("姓名");titleArr.add("欠款");titleArr.add("存款");List<String> fldNameArr = new ArrayList<String>();// 字段名fldNameArr.add("item1");fldNameArr.add("item2");fldNameArr.add("item3");// 数据集合List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();// 第一行数据Map<String, String> base1 = new HashMap<String, String>();base1.put("item1", "老张");base1.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base1.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第二行数据Map<String, String> base2 = new HashMap<String, String>();base2.put("item1", "老李");base2.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base2.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第三行数据Map<String, String> base3 = new HashMap<String, String>();base3.put("item1", "老刘");base3.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base3.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");listItemsByType.add(base1);listItemsByType.add(base2);listItemsByType.add(base3);POIXMLDocumentPart poixmlDocumentPart2 = chartsMap.get("/word/charts/chart3.xml");PoiWordTools.replaceBarCharts(poixmlDocumentPart2, titleArr, fldNameArr, listItemsByType);}public static void doCharts4(Map<String, POIXMLDocumentPart> chartsMap) {// 数据准备List<String> titleArr = new ArrayList<String>();// 标题titleArr.add("title");titleArr.add("占基金资产净值比例22222(%)");titleArr.add("额外的(%)");titleArr.add("额外的(%)");List<String> fldNameArr = new ArrayList<String>();// 字段名fldNameArr.add("item1");fldNameArr.add("item2");fldNameArr.add("item3");fldNameArr.add("item4");// 数据集合List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();// 第一行数据Map<String, String> base1 = new HashMap<String, String>();base1.put("item1", "材料费用");base1.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base1.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base1.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第二行数据Map<String, String> base2 = new HashMap<String, String>();base2.put("item1", "出差费用");base2.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base2.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base2.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第三行数据Map<String, String> base3 = new HashMap<String, String>();base3.put("item1", "住宿费用");base3.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base3.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base3.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");listItemsByType.add(base1);listItemsByType.add(base2);listItemsByType.add(base3);POIXMLDocumentPart poixmlDocumentPart2 = chartsMap.get("/word/charts/chart4.xml");PoiWordTools.replaceLineCharts(poixmlDocumentPart2, titleArr, fldNameArr, listItemsByType);}/*** 对应文档中的第6个图表(预处理—分公司情况)*/public static void doCharts6(Map<String, POIXMLDocumentPart> chartsMap) {// 数据准备List<String> titleArr = new ArrayList<String>();// 标题titleArr.add("title");titleArr.add("投诉受理量(次)");titleArr.add("预处理拦截工单量(次)");titleArr.add("拦截率");List<String> fldNameArr = new ArrayList<String>();// 字段名fldNameArr.add("item1");fldNameArr.add("item2");fldNameArr.add("item3");fldNameArr.add("item4");// 数据集合List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();// 第一行数据Map<String, String> base1 = new HashMap<String, String>();base1.put("item1", "通辽");base1.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base1.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base1.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第二行数据Map<String, String> base2 = new HashMap<String, String>();base2.put("item1", "呼和浩特");base2.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base2.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base2.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第三行数据Map<String, String> base3 = new HashMap<String, String>();base3.put("item1", "锡林郭勒");base3.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base3.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base3.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第四行数据Map<String, String> base4 = new HashMap<String, String>();base4.put("item1", "阿拉善");base4.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base4.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base4.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第五行数据Map<String, String> base5 = new HashMap<String, String>();base5.put("item1", "巴彦淖尔");base5.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base5.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base5.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第六行数据Map<String, String> base6 = new HashMap<String, String>();base6.put("item1", "兴安");base6.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base6.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base6.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第七行数据Map<String, String> base7 = new HashMap<String, String>();base7.put("item1", "乌兰察布");base7.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base7.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base7.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第八行数据Map<String, String> base8 = new HashMap<String, String>();base8.put("item1", "乌海");base8.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base8.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base8.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第九行数据Map<String, String> base9 = new HashMap<String, String>();base9.put("item1", "赤峰");base9.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base9.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base9.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第十行数据Map<String, String> base10 = new HashMap<String, String>();base10.put("item1", "包头");base10.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base10.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base10.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第十一行数据Map<String, String> base11 = new HashMap<String, String>();base11.put("item1", "呼伦贝尔");base11.put("item2", (int)(int)(1 + Math.random() * (100 - 1 + 1)) + "");base11.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base11.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");// 第十二行数据Map<String, String> base12 = new HashMap<String, String>();base12.put("item1", "鄂尔多斯");base12.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base12.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");base12.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");listItemsByType.add(base1);listItemsByType.add(base2);listItemsByType.add(base3);listItemsByType.add(base4);listItemsByType.add(base5);listItemsByType.add(base6);listItemsByType.add(base7);listItemsByType.add(base8);listItemsByType.add(base9);listItemsByType.add(base10);listItemsByType.add(base11);listItemsByType.add(base12);// 下标0的图表-折线图POIXMLDocumentPart poixmlDocumentPart5 = chartsMap.get("/word/charts/chart6.xml");PoiWordTools.replaceCombinationCharts(poixmlDocumentPart5, titleArr, fldNameArr, listItemsByType);}}

工具类也是参考的加上游客的意见

package com.turing.report.controller;import org.apache.poi.ooxml.POIXMLDocumentPart;
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.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.XWPFChart;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.openxmlformats.schemas.drawingml.x2006.chart.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.stereotype.Component;import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;/*** poi生成word的工具类*/
@Component
public class PoiWordTools {private static final BigDecimal bd2 = new BigDecimal("2");/*** 调用替换柱状图数据*/public static void replaceBarCharts(POIXMLDocumentPart poixmlDocumentPart,List<String> titleArr, List<String> fldNameArr, List<Map<String, String>> listItemsByType) {XWPFChart chart = (XWPFChart) poixmlDocumentPart;chart.getCTChart();//根据属性第一列名称切换数据类型CTChart ctChart = chart.getCTChart();CTPlotArea plotArea = ctChart.getPlotArea();CTBarChart barChart = plotArea.getBarChartArray(0);List<CTBarSer> BarSerList = barChart.getSerList();  // 获取柱状图单位//刷新内置excel数据refreshExcel(chart, listItemsByType, fldNameArr, titleArr);//刷新页面显示数据refreshBarStrGraphContent(barChart, BarSerList, listItemsByType, fldNameArr, 1);}/*** 调用替换折线图数据*/public static void replaceLineCharts(POIXMLDocumentPart poixmlDocumentPart,List<String> titleArr, List<String> fldNameArr, List<Map<String, String>> listItemsByType) {XWPFChart chart = (XWPFChart) poixmlDocumentPart;chart.getCTChart();//根据属性第一列名称切换数据类型CTChart ctChart = chart.getCTChart();CTPlotArea plotArea = ctChart.getPlotArea();CTLineChart lineChart = plotArea.getLineChartArray(0);List<CTLineSer> lineSerList = lineChart.getSerList();   // 获取折线图单位//刷新内置excel数据refreshExcel(chart, listItemsByType, fldNameArr, titleArr);//刷新页面显示数据refreshLineStrGraphContent(lineChart, lineSerList, listItemsByType, fldNameArr, 1);}/*** 调用替换饼图数据*/public static void replacePieCharts(POIXMLDocumentPart poixmlDocumentPart,List<String> titleArr, List<String> fldNameArr, List<Map<String, String>> listItemsByType) {XWPFChart chart = (XWPFChart) poixmlDocumentPart;chart.getCTChart();//根据属性第一列名称切换数据类型CTChart ctChart = chart.getCTChart();CTPlotArea plotArea = ctChart.getPlotArea();CTPieChart pieChart = plotArea.getPieChartArray(0);List<CTPieSer> pieSerList = pieChart.getSerList();  // 获取饼图单位//刷新内置excel数据refreshExcel(chart, listItemsByType, fldNameArr, titleArr);//刷新页面显示数据refreshPieStrGraphContent(pieChart, pieSerList, listItemsByType, fldNameArr, 1);}/*** 调用替换柱状图、折线图组合数据*/public static void replaceCombinationCharts(POIXMLDocumentPart poixmlDocumentPart,List<String> titleArr, List<String> fldNameArr, List<Map<String, String>> listItemsByType) {XWPFChart chart = (XWPFChart) poixmlDocumentPart;chart.getCTChart();//根据属性第一列名称切换数据类型CTChart ctChart = chart.getCTChart();CTPlotArea plotArea = ctChart.getPlotArea();CTBarChart barChart = plotArea.getBarChartArray(0);List<CTBarSer> barSerList = barChart.getSerList();  // 获取柱状图单位//刷新内置excel数据refreshExcel(chart, listItemsByType, fldNameArr, titleArr);//刷新页面显示数据refreshBarStrGraphContent(barChart, barSerList, listItemsByType, fldNameArr, 1);CTBarChart barChart2 = plotArea.getBarChartArray(0);List<CTBarSer> barSerList2 = barChart2.getSerList();  // 获取柱状图单位//刷新内置excel数据refreshExcel(chart, listItemsByType, fldNameArr, titleArr);//刷新页面显示数据refreshBarStrGraphContent(barChart2, barSerList2, listItemsByType, fldNameArr, 1);CTLineChart lineChart = plotArea.getLineChartArray(0);List<CTLineSer> lineSerList = lineChart.getSerList();   // 获取折线图单位//刷新内置excel数据refreshExcel(chart, listItemsByType, fldNameArr, titleArr);//刷新页面显示数据refreshLineStrGraphContent(lineChart, lineSerList, listItemsByType, fldNameArr, 1);}/*** 刷新折线图数据方法** @param typeChart* @param serList* @param dataList* @param fldNameArr* @param position* @return*/public static boolean refreshLineStrGraphContent(Object typeChart,List<?> serList, List<Map<String, String>> dataList, List<String> fldNameArr, int position) {boolean result = true;//更新数据区域for (int i = 0; i < serList.size(); i++) {//CTSerTx tx=null;CTAxDataSource cat = null;CTNumDataSource val = null;CTLineSer ser = ((CTLineChart) typeChart).getSerArray(i);//tx= ser.getTx();// Category Axis Datacat = ser.getCat();// 获取图表的值val = ser.getVal();// strData.setCTStrData strData = cat.getStrRef().getStrCache();CTNumData numData = val.getNumRef().getNumCache();strData.setPtArray((CTStrVal[]) null); // unset old axis textnumData.setPtArray((CTNumVal[]) null); // unset old values// set modellong idx = 0;for (int j = 0; j < dataList.size(); j++) {//判断获取的值是否为空String value = "0";if (new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))) != null) {value = new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))).toString();}if (!"0".equals(value)) {CTNumVal numVal = numData.addNewPt();//序列值numVal.setIdx(idx);numVal.setV(value);}CTStrVal sVal = strData.addNewPt();//序列名称sVal.setIdx(idx);sVal.setV(dataList.get(j).get(fldNameArr.get(0)));idx++;}numData.getPtCount().setVal(idx);strData.getPtCount().setVal(idx);//赋值横坐标数据区域String axisDataRange = new CellRangeAddress(1, dataList.size(), 0, 0).formatAsString("Sheet1", false);cat.getStrRef().setF(axisDataRange);//数据区域String numDataRange = new CellRangeAddress(1, dataList.size(), i + position, i + position).formatAsString("Sheet1", false);val.getNumRef().setF(numDataRange);// 设置系列生成方向}return result;}/*** 刷新柱状图数据方法** @param typeChart* @param serList* @param dataList* @param fldNameArr* @param position* @return*/public  static boolean refreshBarStrGraphContent(Object typeChart,List<?> serList, List<Map<String, String>> dataList, List<String> fldNameArr, int position) {boolean result = true;//更新数据区域for (int i = 0; i < serList.size(); i++) {//CTSerTx tx=null;CTAxDataSource cat = null;CTNumDataSource val = null;CTBarSer ser = ((CTBarChart) typeChart).getSerArray(i);//tx= ser.getTx();// Category Axis Datacat = ser.getCat();// 获取图表的值val = ser.getVal();// strData.setCTStrData strData = cat.getStrRef().getStrCache();CTNumData numData = val.getNumRef().getNumCache();strData.setPtArray((CTStrVal[]) null); // unset old axis textnumData.setPtArray((CTNumVal[]) null); // unset old values// set modellong idx = 0;for (int j = 0; j < dataList.size(); j++) {//判断获取的值是否为空String value = "0";if (new BigDecimal(dataList.get(j).get(fldNameArr.get(i+position))) != null) {value = new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))).toString();}if (!"0".equals(value)) {CTNumVal numVal = numData.addNewPt();//序列值numVal.setIdx(idx);numVal.setV(value);}CTStrVal sVal = strData.addNewPt();//序列名称sVal.setIdx(idx);sVal.setV(dataList.get(j).get(fldNameArr.get(0)));idx++;}numData.getPtCount().setVal(idx);strData.getPtCount().setVal(idx);//赋值横坐标数据区域String axisDataRange = new CellRangeAddress(1, dataList.size(), 0, 0).formatAsString("Sheet1", true);cat.getStrRef().setF(axisDataRange);//数据区域String numDataRange = new CellRangeAddress(1, dataList.size(), i + position, i + position).formatAsString("Sheet1", true);val.getNumRef().setF(numDataRange);}return result;}/*** 刷新饼图数据方法** @param typeChart* @param serList* @param dataList* @param fldNameArr* @param position* @return*/public static boolean refreshPieStrGraphContent(Object typeChart,List<?> serList, List<Map<String, String>> dataList, List<String> fldNameArr, int position) {boolean result = true;//更新数据区域for (int i = 0; i < serList.size(); i++) {//CTSerTx tx=null;CTAxDataSource cat = null;CTNumDataSource val = null;CTPieSer ser = ((CTPieChart) typeChart).getSerArray(i);//tx= ser.getTx();// Category Axis Datacat = ser.getCat();// 获取图表的值val = ser.getVal();// strData.setCTStrData strData = cat.getStrRef().getStrCache();CTNumData numData = val.getNumRef().getNumCache();strData.setPtArray((CTStrVal[]) null); // unset old axis textnumData.setPtArray((CTNumVal[]) null); // unset old values// set modellong idx = 0;for (int j = 0; j < dataList.size(); j++) {//判断获取的值是否为空String value = "0";if (new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))) != null) {value = new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))).toString();}if (!"0".equals(value)) {CTNumVal numVal = numData.addNewPt();//序列值numVal.setIdx(idx);numVal.setV(value);}CTStrVal sVal = strData.addNewPt();//序列名称sVal.setIdx(idx);sVal.setV(dataList.get(j).get(fldNameArr.get(0)));idx++;}numData.getPtCount().setVal(idx);strData.getPtCount().setVal(idx);//赋值横坐标数据区域String axisDataRange = new CellRangeAddress(1, dataList.size(), 0, 0).formatAsString("Sheet1", true);cat.getStrRef().setF(axisDataRange);//数据区域String numDataRange = new CellRangeAddress(1, dataList.size(), i + position, i + position).formatAsString("Sheet1", true);val.getNumRef().setF(numDataRange);}return result;}/*** 刷新内置excel数据** @param chart* @param dataList* @param fldNameArr* @param titleArr* @return*/public static boolean refreshExcel(XWPFChart chart,List<Map<String, String>> dataList, List<String> fldNameArr, List<String> titleArr) {boolean result = true;Workbook wb = new XSSFWorkbook();Sheet sheet = wb.createSheet("Sheet1");//根据数据创建excel第一行标题行for (int i = 0; i < titleArr.size(); i++) {if (sheet.getRow(0) == null) {sheet.createRow(0).createCell(i).setCellValue(titleArr.get(i) == null ? "" : titleArr.get(i));} else {sheet.getRow(0).createCell(i).setCellValue(titleArr.get(i) == null ? "" : titleArr.get(i));}}//遍历数据行for (int i = 0; i < dataList.size(); i++) {Map<String, String> baseFormMap = dataList.get(i);//数据行//fldNameArr字段属性for (int j = 0; j < fldNameArr.size(); j++) {if (sheet.getRow(i + 1) == null) {if (j == 0) {try {sheet.createRow(i + 1).createCell(j).setCellValue(baseFormMap.get(fldNameArr.get(j)) == null ? "" : baseFormMap.get(fldNameArr.get(j)));} catch (Exception e) {if (baseFormMap.get(fldNameArr.get(j)) == null) {sheet.createRow(i + 1).createCell(j).setCellValue("");} else {sheet.createRow(i + 1).createCell(j).setCellValue(baseFormMap.get(fldNameArr.get(j)));}}}} else {BigDecimal b = new BigDecimal(baseFormMap.get(fldNameArr.get(j)));double value = 0d;if (b != null) {value = b.doubleValue();}if (value == 0) {sheet.getRow(i + 1).createCell(j);} else {sheet.getRow(i + 1).createCell(j).setCellValue(b.doubleValue());}}}}// 更新嵌入的workbookList<POIXMLDocumentPart> pxdList = chart.getRelations();if(pxdList!=null&&pxdList.size()>0){for(int i = 0;i<pxdList.size();i++){if(pxdList.get(i).toString().contains("sheet")){//判断为sheet再去进行更新表格数据POIXMLDocumentPart xlsPart =  pxdList.get(i);OutputStream xlsOut = xlsPart.getPackagePart().getOutputStream();try {wb.write(xlsOut);xlsOut.close();} catch (IOException e) {e.printStackTrace();result = false;} finally {if (wb != null) {try {wb.close();} catch (IOException e) {e.printStackTrace();result = false;}}}break;}}}return result;}/*** 设置表格样式** @param cell* @param fontName* @param fontSize* @param fontBlod* @param alignment* @param vertical* @param fontColor* @param bgColor* @param cellWidth* @param content*/public static void setWordCellSelfStyle(XWPFTableCell cell, String fontName, String fontSize, int fontBlod,String alignment, String vertical, String fontColor,String bgColor, String cellWidth, String content) {//poi对字体大小设置特殊,不支持小数,但对原word字体大小做了乘2处理BigInteger bFontSize = new BigInteger("24");if (fontSize != null && !fontSize.equals("")) {//poi对字体大小设置特殊,不支持小数,但对原word字体大小做了乘2处理BigDecimal fontSizeBD = new BigDecimal(fontSize);fontSizeBD = bd2.multiply(fontSizeBD);fontSizeBD = fontSizeBD.setScale(0, BigDecimal.ROUND_HALF_UP);//这里取整bFontSize = new BigInteger(fontSizeBD.toString());// 字体大小}// 设置单元格宽度cell.setWidth(cellWidth);//=====获取单元格CTTc tc = cell.getCTTc();//====tcPr开始====》》》》CTTcPr tcPr = tc.getTcPr();//获取单元格里的<w:tcPr>if (tcPr == null) {//没有<w:tcPr>,创建tcPr = tc.addNewTcPr();}//  --vjc开始-->>CTVerticalJc vjc = tcPr.getVAlign();//获取<w:tcPr>  的<w:vAlign w:val="center"/>if (vjc == null) {//没有<w:w:vAlign/>,创建vjc = tcPr.addNewVAlign();}//设置单元格对齐方式vjc.setVal(vertical.equals("top") ? STVerticalJc.TOP : vertical.equals("bottom") ? STVerticalJc.BOTTOM : STVerticalJc.CENTER); //垂直对齐CTShd shd = tcPr.getShd();//获取<w:tcPr>里的<w:shd w:val="clear" w:color="auto" w:fill="C00000"/>if (shd == null) {//没有<w:shd>,创建shd = tcPr.addNewShd();}// 设置背景颜色shd.setFill(bgColor.substring(1));//《《《《====tcPr结束====//====p开始====》》》》CTP p = tc.getPList().get(0);//获取单元格里的<w:p w:rsidR="00C36068" w:rsidRPr="00B705A0" w:rsidRDefault="00C36068" w:rsidP="00C36068">//---ppr开始--->>>CTPPr ppr = p.getPPr();//获取<w:p>里的<w:pPr>if (ppr == null) {//没有<w:pPr>,创建ppr = p.addNewPPr();}//  --jc开始-->>CTJc jc = ppr.getJc();//获取<w:pPr>里的<w:jc w:val="left"/>if (jc == null) {//没有<w:jc/>,创建jc = ppr.addNewJc();}//设置单元格对齐方式jc.setVal(alignment.equals("left") ? STJc.LEFT : alignment.equals("right") ? STJc.RIGHT : STJc.CENTER); //水平对齐//  <<--jc结束--//  --pRpr开始-->>CTParaRPr pRpr = ppr.getRPr(); //获取<w:pPr>里的<w:rPr>if (pRpr == null) {//没有<w:rPr>,创建pRpr = ppr.addNewRPr();}CTFonts pfont = pRpr.getRFonts();//获取<w:rPr>里的<w:rFonts w:ascii="宋体" w:eastAsia="宋体" w:hAnsi="宋体"/>if (pfont == null) {//没有<w:rPr>,创建pfont = pRpr.addNewRFonts();}//设置字体pfont.setAscii(fontName);pfont.setEastAsia(fontName);pfont.setHAnsi(fontName);CTOnOff pb = pRpr.getB();//获取<w:rPr>里的<w:b/>if (pb == null) {//没有<w:b/>,创建pb = pRpr.addNewB();}//设置字体是否加粗pb.setVal(fontBlod == 1 ? STOnOff.ON : STOnOff.OFF);CTHpsMeasure psz = pRpr.getSz();//获取<w:rPr>里的<w:sz w:val="32"/>if (psz == null) {//没有<w:sz w:val="32"/>,创建psz = pRpr.addNewSz();}// 设置单元格字体大小psz.setVal(bFontSize);CTHpsMeasure pszCs = pRpr.getSzCs();//获取<w:rPr>里的<w:szCs w:val="32"/>if (pszCs == null) {//没有<w:szCs w:val="32"/>,创建pszCs = pRpr.addNewSzCs();}// 设置单元格字体大小pszCs.setVal(bFontSize);//  <<--pRpr结束--//<<<---ppr结束---//---r开始--->>>List<CTR> rlist = p.getRList(); //获取<w:p>里的<w:r w:rsidRPr="00B705A0">CTR r = null;if (rlist != null && rlist.size() > 0) {//获取第一个<w:r>r = rlist.get(0);} else {//没有<w:r>,创建r = p.addNewR();}//--rpr开始-->>CTRPr rpr = r.getRPr();//获取<w:r w:rsidRPr="00B705A0">里的<w:rPr>if (rpr == null) {//没有<w:rPr>,创建rpr = r.addNewRPr();}//->-CTFonts font = rpr.getRFonts();//获取<w:rPr>里的<w:rFonts w:ascii="宋体" w:eastAsia="宋体" w:hAnsi="宋体" w:hint="eastAsia"/>if (font == null) {//没有<w:rFonts>,创建font = rpr.addNewRFonts();}//设置字体font.setAscii(fontName);font.setEastAsia(fontName);font.setHAnsi(fontName);CTOnOff b = rpr.getB();//获取<w:rPr>里的<w:b/>if (b == null) {//没有<w:b/>,创建b = rpr.addNewB();}//设置字体是否加粗b.setVal(fontBlod == 1 ? STOnOff.ON : STOnOff.OFF);CTColor color = rpr.getColor();//获取<w:rPr>里的<w:color w:val="FFFFFF" w:themeColor="background1"/>if (color == null) {//没有<w:color>,创建color = rpr.addNewColor();}// 设置字体颜色if (content.contains("↓")) {color.setVal("43CD80");} else if (content.contains("↑")) {color.setVal("943634");} else {color.setVal(fontColor.substring(1));}CTHpsMeasure sz = rpr.getSz();if (sz == null) {sz = rpr.addNewSz();}sz.setVal(bFontSize);CTHpsMeasure szCs = rpr.getSzCs();if (szCs == null) {szCs = rpr.addNewSz();}szCs.setVal(bFontSize);//-<-//<<--rpr结束--List<CTText> tlist = r.getTList();CTText t = null;if (tlist != null && tlist.size() > 0) {//获取第一个<w:r>t = tlist.get(0);} else {//没有<w:r>,创建t = r.addNewT();}t.setStringValue(content);//<<<---r结束---}}

模板需要按照楼主的模板来做

java使用poi在word中生成柱状图、折线图、饼图、柱状图+折线图组合图、动态表格、文本替换、图片替换 springboot项目相关推荐

  1. java使用poi在word中生成柱状图、折线图、饼图、柱状图+折线图组合图、动态表格、文本替换、图片替换、更新内置Excel数据、更新插入的文本框内容、合并表格单元格;

    本文参考地址:https://blog.csdn.net/wangxiaoyingWXY/article/details/95377533 在参考文章的基础上,增加了扩展.感谢被参考的妹子.另外该博客 ...

  2. 使用java Apache poi 根据word模板生成word报表

    使用java Apache poi 根据word模板生成word报表 使用poi读取word模板,替换word中的{text}标签,并根据自定义标签循环生成表格或表格中的行. 代码示例下载:https ...

  3. java使用poi读写word中的图片(二)

    文章目录 准备工作 简单读取 复杂读取 查看Word的XML 特别说明:Word中的Svg图片 第一种写入图片到Word中的方式 第二种写入图片到Word中的方式 最后 准备工作 这里就不在复述了,可 ...

  4. 【Apache Poi】如何使用poi在word中生成复选框

    如何使用poi在word中生成复选框 应用场景 解决方式 代码示例 结语 应用场景 我们经常会在开发中遇到需要通过Poi来生成类似下面这样的复选框 解决方式 我们可以通过unicode编码:\u25A ...

  5. apache poi使用例_使用java Apache poi 根据word模板生成word报表例子

    [实例简介] 使用java Apache poi 根据word模板生成word报表 仅支持docx格式的word文件,大概是word2010及以后版本,doc格式不支持. 使用说明:https://b ...

  6. java利用POI在word中绘制折线图

    1.poi的简介 Apache POI 简介是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office(Excel.WORD ...

  7. poi编辑word中的chart,对图表数据替换,并刷新图表

    最近工作需要做报表导出,再次接触poi,上次用poi的时候还是上次(在前司编辑excel的时候). 而word呢,数据结构上感觉又比excel复杂,至少我处理的时候认为是这样. 首先看一下要处理的wo ...

  8. 记录java使用POI实现word模板数据填充

    一.前言 最近项目遇到个需求,在模板中填充数据,刚开始是用smartBi报表进行填充,输出参数都是必录,无法满足需求.在网上查了很多资料,有些需要把文档转成xml格式修改里面内容,IDEA里面修改要替 ...

  9. excel中如何使内容不要超出单元格

    https://jingyan.baidu.com/article/cd4c2979bf38bb356f6e6006.html 以上是原文链接 摘要: 首先,在桌面点击鼠标右键,点击"新建& ...

最新文章

  1. 38.什么是PV操作
  2. 8 list切片_Python中14个切片操作,你常用哪几个?
  3. 常见八种安卓开发报错的方式
  4. node项目正常启动后不能访问(防火墙未放行端口)
  5. @Aspect中@Pointcut 12种用法
  6. ajax传递map参数给后端
  7. 潘石屹没跑,他去学 Python 了
  8. ckc交易什么意思_在期货交易中,所谓的期货对冲是什么意思?
  9. 使用SAS实现单因素方差分析
  10. html设置字体为小型大写字母,css – 启用小型大写字母
  11. 借助微博实时号日引流200精准客源,微博实时号是什么?
  12. Android apk安装报错:应用未安装 软件包似乎已损坏
  13. 负载均衡及其常见实现方式
  14. virtuoso 安装与使用
  15. ros::Rate loop_rate(10); loop_rate.sleep(); 在程序中是休眠到一定时间,并不占用CPU时间
  16. 用计算机术语写毕业寄语,毕业寄语大全一句话
  17. 程序员赚零钱食用指南
  18. Spring Boot 使用 QQ邮箱发邮件
  19. 我们分析了金庸小说中出现的1367个人物名字,发现了一些相当惊人的事情
  20. 如何在Word中创建和打印标签

热门文章

  1. 缓解核心交换机网线过多的设计思路
  2. 从浏览器输入URL到页面显示的过程
  3. 扫地机器人系统,主要划分为哪几个模块?
  4. 【iOS】苹果登录Sign in with Apple
  5. 皮卡智能联手全球最大贸易服务商PingPong,共推AIGC应用落地服务
  6. 安全教育平台显示服务器繁忙,为什么安全教育平台登录不上 安全教育平台登录不上是什么原因...
  7. markdown文章发布到csdn和微信公众号
  8. 1.3双摇杆遥控器电路部分--基本外设电路(ST-link下载、串口、按键、摇杆、电量检测、LED指示灯、0.96寸OLED、NRF24L01)
  9. matlab设置x轴和y轴的坐标显示范围和刻度
  10. linux cpu降频怎么设置,Android系统修改CPU降频温度阈值、修改CPU关内核温度阈值的方法...