关于使用apache POI使用既有模版生成doc文档的技术记录

关于使用apache POI使用既有模版生成word文档的技术记录

1.使用依赖

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

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.1.2</version>
        </dependency>

2.关于折现统计图的生成

在这里插入图片描述

1.首先在word 的文档中插入一张随机的折现统计图(因为实际需要所以我本地的模板有两张折现统计图)

2.插入统计图以后基于统计图对样式做出修改和调整,具体基于实际业务场景进行操作

3.编写代码

//1.获取图表模板
 String templatePath = "D:\\youxi\\module1.docx";
// 获取doc文件模板
try{
    InputStream is = new FileInputStream(new File(templatePath));
    doc = new XWPFDocument(is);
}catch (Exception e){
    e.printStackTrace();
}
//2.获取图表信息
List<XWPFChart> list = doc.getCharts();//知道具体几张表
// 操作图表
//1图, 每条线的名称,一张图可以有多条线,每条线可以有多个名称,使用字符数组命名
String[] series1 = {"测试折线1","",""};
//2图,同上
String[] series2 = {"测试折线"};

//给统计图命名标题说明是什么折现统计图
String title1="测试折线图1";
String title2="测试折线图2";

//y轴
List<Number[]> value1 = new ArrayList<>();//每一张折线图,第一个表3条,需要和图中条数一样
List<Number[]> value2 = new ArrayList<>();//每一张折线图,第二个表1条
//第一张图的y轴
Number[] n1={1.02f,0.5f,-0.3f,0.2f,0.55f,2.6f,1.02f,0.5f,-0.3f,0.2f,0.55f,2.6f,1.02f,0.5f,-0.3f,0.2f,0.55f,2.6f,3.0f,-2.45f};
Number[] n2={4,2,1,4};
Number[] n3={5.8,6.2,1,0.2};
value1.add(n1);
value1.add(n2);
value1.add(n3);
//第二张图的y轴
Number[] n={35, 56, 70, 20, 30,210,35, 56, 70, 20, 30,210,35, 56, 70, 20, 30,210, 10, -20};
value2.add(n);
//定义x轴  y轴和x轴一样都用数组的形式包装数据 如果两张图x轴取参不一样同样需要写入x2作为第二张图的x轴
String[] x1={"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"};

XWPFChart xChart1 = doc.getCharts().get(0);//获取第1个图表
XWPFChart xChart2 = doc.getCharts().get(1);//获取第2个图表

//此处生成折线统计图
drawLineChart(xChart1,series1,x1,value1,title1);
drawLineChart(xChart2,series2,x1,value2,title2);

生成折线统计图方法
//chart 图表
//series 折线名
//categories x轴
//values y轴数据
//chartTitle 统计图名称
public static void drawLineChart(XWPFChart chart, String[] series, String[] categories,
                                     List<Number[]> values, String chartTitle){
        final List<XDDFChartData> data = chart.getChartSeries();

        final XDDFLineChartData line = (XDDFLineChartData) data.get(0);//这里一般获取第一个,我们这里是折线图就是XDDFLineChartData

        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);
    }

3.操作表格数据

在这里插入图片描述

1.基于实际业务编写我们所需要的表格模版

2.编写代码

//获取表格 因为我只有一个表 就直接get(0)
XWPFTable tables = doc.getTables().get(0);
//获取所有行行
List<XWPFTableRow> rows = tables.getRows();
//遍历行获取单元格
for (int i = 0; i < rows.size(); i ++) {
    XWPFTableRow row = rows.get(i);
    //遍历行里单元格 在单元格内写入数据 此处写入数据需要基于业务自己调试 
    for (XWPFTableCell cell : row.getTableCells()){
        cell.setText(String.valueOf(Math.random()));
    }
}

4.操作参数替换

在这里插入图片描述

Map<String, String> map = new HashMap<>();
map.put("${template}", "测试信息");
map.put("${templatee}", "2023-05-16");
map.put("${barLine}", "000123");
//获取所有段落
List<XWPFParagraph> paragraphList = doc.getParagraphs();
for (XWPFParagraph par : paragraphList) {
    //获取段落的文本对象
    List<XWPFRun> runs = par.getRuns();
    for (XWPFRun run : runs) {
        //获取文本的值
        String text = run.getText(0);
        //遍历map
        for (Map.Entry<String, String> entry : map.entrySet()) {
            //获取map的key
            String key = entry.getKey();
            //判断文本的值和map的key,文本中是否有和key一样的占位符
            if (text.indexOf(key) != -1) {
                //获取对应key的value
                Object value = entry.getValue();
                //把文本的内容,key替换为value
                text = text.replace(key, value.toString());
                //把替换好的文本内容,保存到当前这个文本对象
                run.setText(text, 0);
            }
        }

    }
}

注意: 在操作前需要使用$占位符, 当前占位符可以识别需要替换的数据信息, 如果在表格中需要添加占位符数据,则需要在cell中操作此方法编辑

5.操作模版页眉使用占位符修改如作者证书编号等信息

在这里插入图片描述

XWPFHeaderFooterPolicy headerFooterPolicy = doc.getHeaderFooterPolicy();
XWPFHeader header = headerFooterPolicy.getDefaultHeader();
List<XWPFParagraph> paragraphs = header.getParagraphs();
 //因为此处只有一行  只有一个参数直接可以操作  无需进行匹配如上述占位符匹配 如果是多个的情况还是如上述占位符的方式进行遍历匹配
paragraphs.get(0).getRuns().get(3).setText("John Doe",0);

6.输出已写完的参数信息

try (
    FileOutputStream fos = new FileOutputStream("D:\\youxi\\moduleServer.docx")) {
    doc.write(fos);
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值