java使用poi在word中生成柱状图、折线图、饼图、柱状图+折线图组合图、动态表格、文本替换、图片替换 springboot项目
本文参考地址: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项目相关推荐
- java使用poi在word中生成柱状图、折线图、饼图、柱状图+折线图组合图、动态表格、文本替换、图片替换、更新内置Excel数据、更新插入的文本框内容、合并表格单元格;
本文参考地址:https://blog.csdn.net/wangxiaoyingWXY/article/details/95377533 在参考文章的基础上,增加了扩展.感谢被参考的妹子.另外该博客 ...
- 使用java Apache poi 根据word模板生成word报表
使用java Apache poi 根据word模板生成word报表 使用poi读取word模板,替换word中的{text}标签,并根据自定义标签循环生成表格或表格中的行. 代码示例下载:https ...
- java使用poi读写word中的图片(二)
文章目录 准备工作 简单读取 复杂读取 查看Word的XML 特别说明:Word中的Svg图片 第一种写入图片到Word中的方式 第二种写入图片到Word中的方式 最后 准备工作 这里就不在复述了,可 ...
- 【Apache Poi】如何使用poi在word中生成复选框
如何使用poi在word中生成复选框 应用场景 解决方式 代码示例 结语 应用场景 我们经常会在开发中遇到需要通过Poi来生成类似下面这样的复选框 解决方式 我们可以通过unicode编码:\u25A ...
- apache poi使用例_使用java Apache poi 根据word模板生成word报表例子
[实例简介] 使用java Apache poi 根据word模板生成word报表 仅支持docx格式的word文件,大概是word2010及以后版本,doc格式不支持. 使用说明:https://b ...
- java利用POI在word中绘制折线图
1.poi的简介 Apache POI 简介是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office(Excel.WORD ...
- poi编辑word中的chart,对图表数据替换,并刷新图表
最近工作需要做报表导出,再次接触poi,上次用poi的时候还是上次(在前司编辑excel的时候). 而word呢,数据结构上感觉又比excel复杂,至少我处理的时候认为是这样. 首先看一下要处理的wo ...
- 记录java使用POI实现word模板数据填充
一.前言 最近项目遇到个需求,在模板中填充数据,刚开始是用smartBi报表进行填充,输出参数都是必录,无法满足需求.在网上查了很多资料,有些需要把文档转成xml格式修改里面内容,IDEA里面修改要替 ...
- excel中如何使内容不要超出单元格
https://jingyan.baidu.com/article/cd4c2979bf38bb356f6e6006.html 以上是原文链接 摘要: 首先,在桌面点击鼠标右键,点击"新建& ...
最新文章
- 38.什么是PV操作
- 8 list切片_Python中14个切片操作,你常用哪几个?
- 常见八种安卓开发报错的方式
- node项目正常启动后不能访问(防火墙未放行端口)
- @Aspect中@Pointcut 12种用法
- ajax传递map参数给后端
- 潘石屹没跑,他去学 Python 了
- ckc交易什么意思_在期货交易中,所谓的期货对冲是什么意思?
- 使用SAS实现单因素方差分析
- html设置字体为小型大写字母,css – 启用小型大写字母
- 借助微博实时号日引流200精准客源,微博实时号是什么?
- Android apk安装报错:应用未安装 软件包似乎已损坏
- 负载均衡及其常见实现方式
- virtuoso 安装与使用
- ros::Rate loop_rate(10); loop_rate.sleep(); 在程序中是休眠到一定时间,并不占用CPU时间
- 用计算机术语写毕业寄语,毕业寄语大全一句话
- 程序员赚零钱食用指南
- Spring Boot 使用 QQ邮箱发邮件
- 我们分析了金庸小说中出现的1367个人物名字,发现了一些相当惊人的事情
- 如何在Word中创建和打印标签
热门文章
- 缓解核心交换机网线过多的设计思路
- 从浏览器输入URL到页面显示的过程
- 扫地机器人系统,主要划分为哪几个模块?
- 【iOS】苹果登录Sign in with Apple
- 皮卡智能联手全球最大贸易服务商PingPong,共推AIGC应用落地服务
- 安全教育平台显示服务器繁忙,为什么安全教育平台登录不上 安全教育平台登录不上是什么原因...
- markdown文章发布到csdn和微信公众号
- 1.3双摇杆遥控器电路部分--基本外设电路(ST-link下载、串口、按键、摇杆、电量检测、LED指示灯、0.96寸OLED、NRF24L01)
- matlab设置x轴和y轴的坐标显示范围和刻度
- linux cpu降频怎么设置,Android系统修改CPU降频温度阈值、修改CPU关内核温度阈值的方法...