工作中经常会用到 Apache POI去操作Word文档,自己整理了一个工具类,简单实用,其中包含了新建标题、段落、表格、饼图、柱形图、折线图等方法。先上效果图

在pom文件中引入依赖

<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>

添加Word工具类

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTDLbls;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;import java.io.IOException;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** @author fax* @date 2021-08-23 11:08*/
public class WordUtils {/*** 替换文档中的内容** @param doc    Word的文档* @param params 待填充的数据*               params.put("key",value) 文档中对应为 ${key}*/public void replaceInPara(XWPFDocument doc, Map<String, Object> params) {Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();while (iterator.hasNext()) {replaceInPara(iterator.next(), params);}}/*** 遍历所有表格,替换表格里面的变量** @param doc    要替换的文档* @param params 参数*/public void replaceInAllTable(XWPFDocument doc, Map<String, Object> params) {Iterator<XWPFTable> iterator = doc.getTablesIterator();while (iterator.hasNext()) {replaceInTable(iterator.next(), params);}}/*** 替换指定表格中的变量** @param doc* @param tabIndex 表格下标* @param params   替换参数*/public void replaceInTable(XWPFDocument doc, int[] tabIndex, Map<String, Object> params) {List<XWPFTable> tables = doc.getTables();for (int index : tabIndex) {replaceInTable(tables.get(index), params);}}/*** 替换表格中的变量** @param table* @param params*/public void replaceInTable(XWPFTable table, Map<String, Object> params) {List<XWPFTableRow> rows;List<XWPFTableCell> cells;List<XWPFParagraph> paras;//判断表格中是否有 ${} 有就表示需要替换值if (matcher(table.getText()).find()) {rows = table.getRows();for (XWPFTableRow row : rows) {cells = row.getTableCells();for (XWPFTableCell cell : cells) {paras = cell.getParagraphs();for (XWPFParagraph para : paras) {replaceInPara(para, params);}}}}}/*** 在表格中新增行数并填充数据** @param table    需要插入数据的表格* @param rowDatas 插入数据集合(注:填充的数据要与单元格的数量保持一致)*/public void insertTableRow(XWPFTable table, List<String[]> rowDatas) {for (String[] cellDatas : rowDatas) {XWPFTableRow row = table.createRow();List<XWPFTableCell> cells = row.getTableCells();for (int j = 0; j < cells.size(); j++) {cells.get(j).setText(cellDatas[j]);}}}/*** 替换段落里面的变量** @param para   要替换的段落* @param params 参数*/private void replaceInPara(XWPFParagraph para, Map<String, Object> params) {List<XWPFRun> runs;StringBuilder runText = new StringBuilder();if (matcher(para.getParagraphText()).find()) {runs = para.getRuns();int j = runs.size();for (int i = 0; i < j; i++) {runText.append(runs.get(0).toString());//保留最后一个段落,在这段落中替换值,保留原有段落样式if (!((j - 1) == i)) {para.removeRun(0);}}String text = runText.toString();Matcher matcher;while ((matcher = matcher(text)).find()) {text = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));}runs.get(0).setText(text, 0);}}/*** 创建标题** @param paragraph* @param data*/public void createTitle(XWPFParagraph paragraph, String data) {XWPFRun createRun = paragraph.insertNewRun(0);createRun.setText(data);createRun.setFontFamily("宋体");createRun.setFontSize(14);createRun.setBold(true);paragraph.setSpacingAfter(10);paragraph.setSpacingBefore(10);//对齐方式paragraph.setAlignment(ParagraphAlignment.LEFT);}/*** 创建段落** @param paragraph* @param data*/public void createParagraph(XWPFParagraph paragraph, String data) {XWPFRun createRun = paragraph.createRun();createRun.setText(data);createRun.setFontFamily("宋体");createRun.setFontSize(12);paragraph.setFirstLineIndent(20);paragraph.setAlignment(ParagraphAlignment.BOTH);paragraph.setIndentationFirstLine(600);paragraph.setSpacingAfter(10);paragraph.setSpacingBefore(10);}/*** 创建表格** @param document* @param tableList*/public void createTable(XWPFDocument document, List<String[]> tableList) {XWPFTable table = document.createTable(tableList.size(), tableList.get(0).length);//设置表格的宽度CTTblWidth comTableWidth = table.getCTTbl().addNewTblPr().addNewTblW();comTableWidth.setType(STTblWidth.PCT);comTableWidth.setW(BigInteger.valueOf(5000));// 填充数据int length = tableList.size();for (int i = 0; i < length; i++) {XWPFTableRow row = table.getRow(i);List<XWPFTableCell> cells = row.getTableCells();for (int j = 0; j < cells.size(); j++) {cells.get(j).setText(tableList.get(i)[j]);}}}/*** 饼图** @param document* @param title      图的标题* @param valueTitle 图种类名称* @param values     图种类的值*/public void createPieChart(XWPFDocument document, String title, String[] valueTitle, Double[] values) throws IOException, InvalidFormatException {XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);// 标题chart.setTitleText(title);// 标题是否覆盖图表chart.setTitleOverlay(false);// 图例位置XDDFChartLegend legend = chart.getOrAddLegend();legend.setPosition(LegendPosition.TOP_RIGHT);XDDFCategoryDataSource categorys = XDDFDataSourcesFactory.fromArray(valueTitle);XDDFNumericalDataSource<Double> numerical = XDDFDataSourcesFactory.fromArray(values);XDDFChartData data = chart.createData(ChartTypes.PIE, null, null);// 设置为可变颜色data.setVaryColors(true);// 图表加载数据data.addSeries(categorys, numerical);// 绘制chart.plot(data);CTDLbls dLbls = chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).addNewDLbls();dLbls.addNewShowVal().setVal(false);//不显示值dLbls.addNewShowLegendKey().setVal(false);dLbls.addNewShowCatName().setVal(true);//类别名称dLbls.addNewShowSerName().setVal(false);//不显示系列名称dLbls.addNewShowPercent().setVal(true);//显示百分比dLbls.addNewShowLeaderLines().setVal(true); //显示引导线}/*** 柱状图** @param document* @param title      标题* @param xAxisTitle X轴标题* @param yAxisTitle Y轴标题* @param categorys  种类* @param values     值* @throws IOException* @throws InvalidFormatException*/public void createBarChart(XWPFDocument document, String title, String xAxisTitle, String yAxisTitle, String[] categorys, Map<String, Number[]> values) throws IOException, InvalidFormatException {XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);// 标题chart.setTitleText(title);// 标题覆盖chart.setTitleOverlay(false);// 图例位置XDDFChartLegend legend = chart.getOrAddLegend();legend.setPosition(LegendPosition.TOP);legend.setOverlay(true);//X轴属性XDDFCategoryAxis xAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);xAxis.setTitle(xAxisTitle);// Y轴属性XDDFValueAxis yAxis = chart.createValueAxis(AxisPosition.LEFT);yAxis.setTitle(yAxisTitle);yAxis.setCrosses(AxisCrosses.AUTO_ZERO);yAxis.setCrossBetween(AxisCrossBetween.BETWEEN);XDDFChartData data = chart.createData(ChartTypes.BAR, xAxis, yAxis);data.setVaryColors(true);((XDDFBarChartData) data).setBarDirection(BarDirection.COL); // 设置方向为竖状XDDFDataSource<String> categoriesData = XDDFDataSourcesFactory.fromArray(categorys);values.forEach((k, v) -> {XDDFChartData.Series series = data.addSeries(categoriesData, XDDFDataSourcesFactory.fromArray(v));series.setTitle(k, null);});chart.plot(data);}/*** 柱状图** @param document* @param title      标题* @param xAxisTitle X轴标题* @param yAxisTitle Y轴标题* @param categorys  种类* @param values     值* @throws IOException* @throws InvalidFormatException*/public void createLineChart(XWPFDocument document, String title, String xAxisTitle, String yAxisTitle, String[] categorys, Map<String, Number[]> values) throws IOException, InvalidFormatException {XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);// 标题chart.setTitleText(title);// 标题覆盖chart.setTitleOverlay(false);// 图例位置XDDFChartLegend legend = chart.getOrAddLegend();legend.setPosition(LegendPosition.TOP);legend.setOverlay(true);//X轴属性XDDFCategoryAxis xAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);xAxis.setTitle(xAxisTitle);//Y轴属性XDDFValueAxis yAxis = chart.createValueAxis(AxisPosition.LEFT);yAxis.setTitle(yAxisTitle);// 折线图,XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, xAxis, yAxis);XDDFCategoryDataSource countries = XDDFDataSourcesFactory.fromArray(categorys);// 加载数据values.forEach((k, v) -> {XDDFLineChartData.Series series = (XDDFLineChartData.Series) data.addSeries(countries, XDDFDataSourcesFactory.fromArray(v));series.setTitle(k, null); // 折线图例标题series.setMarkerStyle(MarkerStyle.CIRCLE); // 设置标记样式});// 绘制chart.plot(data);}/*** 柱状图** @param document* @param title      标题* @param xAxisTitle X轴标题* @param yAxisTitle Y轴标题* @param categorys  种类* @param values     值* @throws IOException* @throws InvalidFormatException*/public void createBarLineChart(XWPFDocument document, String title, String xAxisTitle, String yAxisTitle, String[] categorys, Map<String, Number[]> values) throws IOException, InvalidFormatException {XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);// 标题chart.setTitleText(title);// 标题覆盖chart.setTitleOverlay(false);// 图例位置XDDFChartLegend legend = chart.getOrAddLegend();legend.setPosition(LegendPosition.TOP);legend.setOverlay(true);//X轴属性XDDFCategoryAxis xAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);xAxis.setTitle(xAxisTitle);//Y轴属性XDDFValueAxis yAxis = chart.createValueAxis(AxisPosition.LEFT);yAxis.setTitle(yAxisTitle);yAxis.setCrosses(AxisCrosses.AUTO_ZERO);yAxis.setCrossBetween(AxisCrossBetween.BETWEEN);// 折线图,XDDFLineChartData lineData = (XDDFLineChartData) chart.createData(ChartTypes.LINE, xAxis, yAxis);// 柱状图XDDFChartData barData = chart.createData(ChartTypes.BAR, xAxis, yAxis);barData.setVaryColors(true);((XDDFBarChartData) barData).setBarDirection(BarDirection.COL); // 设置方向为竖状XDDFCategoryDataSource countries = XDDFDataSourcesFactory.fromArray(categorys);// 加载数据values.forEach((k, v) -> {XDDFChartData.Series barSeries = barData.addSeries(countries, XDDFDataSourcesFactory.fromArray(v));barSeries.setTitle(k, null);XDDFLineChartData.Series lineSeries = (XDDFLineChartData.Series) lineData.addSeries(countries, XDDFDataSourcesFactory.fromArray(v));lineSeries.setTitle(k, null); // 折线图例标题lineSeries.setMarkerStyle(MarkerStyle.CIRCLE); // 设置标记样式});// 绘制chart.plot(lineData);chart.plot(barData);}/*** 正则匹配字符串** @param str* @return*/private Matcher matcher(String str) {Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(str);return matcher;}
}

测试

import com.poi.util.WordUtils;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/** * @author fax* @date 2021-08-23 11:08*/
public class TestWord {public static void main(String[] args) {String content = "马邦德:大风起兮云飞扬,安得猛士兮走四方。" +"匪,任何时候都要剿,不剿不行,你想想,你带着老婆出了城," +"吃着火锅唱着歌,突然就被麻匪劫了,所以,没有麻匪的日子才是好日子!";Map<String, Object> params = new HashMap<>();params.put("title", "让子弹飞");params.put("content", content);params.put("header1", "序号");params.put("header2", "演员");params.put("header3", "角色");params.put("header4", "备注");params.put("header5", "介绍");List<String[]> table1 = new ArrayList<>();table1.add(new String[]{"1", "姜文", "张牧之", "张麻子", "绿林悍匪"});table1.add(new String[]{"2", "周润发", "黄四郎", "黄老爷", "鹅城一霸"});table1.add(new String[]{"2", "葛优", "马邦德", "汤师爷", "只想赚钱"});List<String[]> table2 = new ArrayList<>();table2.add(new String[]{"1", "姜文", "张牧之", "xxx"});table2.add(new String[]{"2", "周润发", "黄四郎", "xxx"});table2.add(new String[]{"3", "葛优", "马邦德", "xxx"});//饼图数据String[] title = new String[]{"1星", "2星", "3星", "4星", "5星"};Double[] value = new Double[]{0.3, 0.5, 5.9, 33.8, 56.2};// 柱状图、折线图 数据String[] quarter = new String[]{"第一季度", "第二季度", "第三季度", "第四季度"};Map<String, Number[]> map = new HashMap<>();map.put("姜文", new Integer[]{6688, 4399, 5327, 6379});map.put("周润发", new Integer[]{6799, 7499, 6429, 7379});map.put("葛优", new Integer[]{5899, 6599, 7665, 8573});System.out.println(System.getProperty("user.dir"));String inPath = System.getProperty("user.dir") + "\\poi_demo\\src\\main\\resources\\template\\Template.docx";String outPath = "D:\\word文件.docx";try (InputStream is = new FileInputStream(inPath);OutputStream os = new FileOutputStream(outPath);XWPFDocument document = new XWPFDocument(OPCPackage.open(is))) {WordUtils wordUtils = new WordUtils();// 替换段落中的参数wordUtils.replaceInPara(document, params);// 替换表格中的参数wordUtils.replaceInTable(document, new int[]{0}, params);// 给表格追加记录wordUtils.insertTableRow(document.getTableArray(0), table1);// 创建表格wordUtils.createTitle(document.createParagraph(), "二、表格二");wordUtils.createTable(document, table2);// 创建饼图wordUtils.createTitle(document.createParagraph(), "三、饼图");wordUtils.createPieChart(document, "豆瓣评分", title, value);wordUtils.createTitle(document.createParagraph(), "四、柱形图");// 创建柱状图wordUtils.createBarChart(document, "标题", null, null, quarter, map);wordUtils.createTitle(document.createParagraph(), "五、条形图");// 创建柱状图wordUtils.createLineChart(document, "标题", "季度", "数值", quarter, map);wordUtils.createTitle(document.createParagraph(), "六、混合图");// 创建柱状图wordUtils.createBarLineChart(document, "标题", null, null, quarter, map);document.write(os);} catch (Exception e) {e.printStackTrace();}}
}

Java poi XWPFDocument 操作2007Word,实现参数替换、新增 插入 替换 表格数据、创建饼状图、柱形图、折线图相关推荐

  1. java poi wps_POI操作WPS表格POI操作WPS表格.docx

    POI操作WPS表格POI操作WPS表格 原文网址:/thread1-1.htmlWps二次开发--POI入门教程一.POI的介绍Apache POI是Apache软件基金会的开放源码函式库,POI提 ...

  2. java poi之操作ppt\pptx

    引言 java poi操作ppt,对ppt进行读写操作 1. 处理pptx格式 pptx格式需要使用XMLSlideShow处理 DealPptX.java 入口函数 @SpringBootTest ...

  3. 使用POI在Excel中动态生成图表工具类(支持柱状、组合、环状图、折线图、等常用图)

    使用POI在Excel中动态生成图表工具类 使用POI在Excel中动态生成图表工具类 由于公司是一个生成报表的机构,之前一直使用pageOffice,但是公司领导就是不买,你说公司那样有钱磨磨唧唧干 ...

  4. java 生成趋势图_JFreeChart折线图的生成方法

    JFreeChart是JAVA平台上的一个开放的图表绘制类库.它完全使用JAVA语言编写,是为applications, applets, servlets 以及JSP等使用所设计.JFreeChar ...

  5. java多按钮筛选条件_Excel办公技巧:如何对表格数据进行自定义筛选?

    这篇文章和大家分享对表格数据进行自定义筛选的两种方法. 应用场景 下图表格中$A$2:$B$10单元格为筛选数据区域,我们想在其中筛选出姓"春"或者姓"夏"同时 ...

  6. 计算机中文字底纹咋操作,电脑word软件怎么为插入的表格设置底纹

    电脑word软件怎么为插入的表格设置底纹 腾讯视频/爱奇艺/优酷/外卖 充值4折起 当我们在使用电脑的时候,如果需要处理文字的话,一般都会用到word软件,那么在word中,怎么为插入的表格添加底纹呢 ...

  7. java poi 读写操作excel

    首先,需要导入poi jar包 package com.road; import java.io.FileNotFoundException; import java.io.FileOutputStr ...

  8. 关于JAVA POI WORD操作的一些心得(少见)

    word模板替换 1.在进行word模板字符进行替换的时候,如果将要进行替换的标签${example}在NotePad++中写好,再将它直接粘贴到word模板的对应位置,那么在使用run对象进行遍历的 ...

  9. Java/poi/ppt操作 — 复制ppt单页放置在指定位置

    1. 需求 使用模板页复制一份一模一样的页面放在指定位置 2.代码 /*** 复制ppt单页* @param template 模板页* @param ppt ppt* @param index 复制 ...

最新文章

  1. 硬核!一文梳理经典图网络模型
  2. php 上万关键字匹配,JavaScript 上万关键字瞬间匹配实现代码
  3. SAP FBCJ现金日记帐增强操作手册
  4. 网络摄像头2 mjpg_streamer流程,编译
  5. 【HTML】底部弹窗插件代码
  6. 第七讲 虚拟机模板及大规模部署虚拟机
  7. 64位整数乘法(类快速幂)
  8. 【18.40%】【codeforces 631D】Messenger
  9. 第三天:完善数据层(controller)真正对接数据库Mysql
  10. 人脸识别python face_recognize_python人脸识别库-face_recognition详解
  11. smtp中mailfrom是必须的吗_人脸识别在建筑工地实名制系统中扮演着什么样的角色,是必须的吗?...
  12. 高德纳(Donald Knuth)语录
  13. 双料大奖 | 奇点云获评「年度数字化创新最佳实践奖」「年度数字化服务最值得信赖品牌奖」
  14. MySQL 排序 输出序号
  15. 元数据是什么?如何管理元数据?
  16. Ubuntu 20.04.2 LTS 系统美化 (UOS主题)
  17. VMware Workstation Ubuntu 20.04 LTS无法连接网络问题
  18. svn执行update操作后出现:Error : Previous operation has not finished; run 'cleanup' if it was interrupted.
  19. 如何认知MOSFET、IGBT等模拟功率器件
  20. java.nio.channels.UnresolvedAddressException: null [运行storm-0.9.4集群时]

热门文章

  1. 倒计时第3天,Google Summer of Code报名即将截止(Casbin社区还有空缺名额)
  2. k3595参数_常用晶体管参数大全
  3. Mysql数据库设计
  4. 西部学刊杂志西部学刊杂志社西部学刊编辑部2022年第22期目录
  5. 云南省增值税发票综合平台(修订版)----发票抵扣勾选教程---
  6. 从AWS S3换成阿里云OSS存储所踩的坑
  7. 2015年最新苹果开发者账号注册流程详解
  8. 使用Busybox制作根文件系统
  9. WPS如何转换成图片?三种方法帮你实现
  10. 「Hudi系列」Hudi查询写入常见问题汇总