写数据到word模板代码

该代码示例展示了如何利用Apache POI库在Java中操作Word文档,包括替换文本和插入表格。通过检查文本中是否包含特定标记来决定是替换内容还是插入新数据,从而实现模板化的Word文档生成。测试代码给出了具体的使用场景,将模板中的占位符替换为实际值,并插入预定义的表格数据。
摘要由CSDN通过智能技术生成

目录

前言

代码

测试代码

 


前言

很多时候都要根据word模板,往里面填充内容,如下图所示,有各种各样不同的表,要往里面填充数据,此处记录代码,以防后续也用。

代码

package com.fable.ntzw.report.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.xwpf.usermodel.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;

/**
 * @author lw
 * @date 2019/11/30 0030
 * @description
 * word工具类
 */
@Slf4j
public class WordToNewWordUtils {

    //每个表格多少表头
    private static int[] headCount = new int[]{2,2,2,2,2,2,2,2,1,1,2,2,2,2};
    //每个表格列数
    private static int[] cellsCount = new int[]{8,8,8,8,7,7,11,11,8,8,6,6,7,7};
    private static int nowTableIndex = -1;

    /**
     * 根据模板生成新word文档
     * 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
     * @param inputUrl 模板存放地址
     * @param outputUrl 新文档存放地址
     * @param textMap 需要替换的信息集合
     * @param tableList 需要插入的表格信息集合
     * @return 成功返回true,失败返回false
     */
    public static boolean changWord(String inputUrl, String outputUrl,
                                    Map<String, String> textMap, List<List<List<String>>> tableList) {

        //模板转换默认成功
        boolean changeFlag = true;
        nowTableIndex = -1;
        try {
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
            //解析替换文本段落对象
            WordToNewWordUtils.changeText(document, textMap);
            //解析替换表格对象
            WordToNewWordUtils.changeTable(document, textMap, tableList);

            //生成新的word
            File file = new File(outputUrl);
            FileOutputStream stream = new FileOutputStream(file);
            document.write(stream);
            stream.close();

        } catch (IOException e) {
            log.error("生成word文档:",e);
            changeFlag = false;
        }

        return changeFlag;

    }

    /**
     * 替换段落文本
     * @param document docx解析对象
     * @param textMap 需要替换的信息集合
     */
    public static void changeText(XWPFDocument document, Map<String, String> textMap){
        //获取段落集合
        List<XWPFParagraph> paragraphs = document.getParagraphs();

        for (XWPFParagraph paragraph : paragraphs) {
            //判断此段落时候需要进行替换
            String text = paragraph.getText();
            if(checkText(text)){
                List<XWPFRun> runs = paragraph.getRuns();
                for (XWPFRun run : runs) {
                    //替换模板原来位置
                    run.setText(changeValue(run.toString(), textMap),0);
                }
            }
        }

    }

    /**
     * 替换表格对象方法
     * @param document docx解析对象
     * @param textMap 需要替换的信息集合
     * @param tableList 需要插入的表格信息集合
     */
    public static void changeTable(XWPFDocument document, Map<String, String> textMap,
                                   List<List<List<String>>> tableList){
        //获取表格对象集合
        List<XWPFTable> tables = document.getTables();
        for (int i = 0; i < tables.size(); i++) {
            //只处理行数大于等于2的表格,且不循环表头
            XWPFTable table = tables.get(i);
            if(table.getRows().size()>1){
                //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
                if(checkText(table.getText())){
                    List<XWPFTableRow> rows = table.getRows();
                    //遍历表格,并替换模板
                    eachTable(rows, textMap);
                }else{
//                  System.out.println("插入"+table.getText());
                    List<List<String>> oneTableContent = tableList.get(i);
                    nowTableIndex++;
                    insertTable(table, oneTableContent);
                }
            }
        }
    }





    /**
     * 遍历表格
     * @param rows 表格行对象
     * @param textMap 需要替换的信息集合
     */
    public static void eachTable(List<XWPFTableRow> rows ,Map<String, String> textMap){
        for (XWPFTableRow row : rows) {
            List<XWPFTableCell> cells = row.getTableCells();
            for (XWPFTableCell cell : cells) {
                //判断单元格是否需要替换
                if(checkText(cell.getText())){
                    List<XWPFParagraph> paragraphs = cell.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs) {
                        List<XWPFRun> runs = paragraph.getRuns();
                        for (XWPFRun run : runs) {
                            run.setText(changeValue(run.toString(), textMap),0);
                        }
                    }
                }
            }
        }
    }

    /**
     * 为表格插入数据,行数不够添加新行
     * @param table 需要插入数据的表格
     * @param tableList 插入数据集合
     */
    public static void insertTable(XWPFTable table, List<List<String>> tableList){
        if(tableList==null||tableList.size()==0){
            return;
        }

        XWPFTableRow modelRow = table.getRow(headCount[nowTableIndex]);

        //创建行,根据需要插入的数据添加新行,不处理表头
        for(int i = 1; i < tableList.size(); i++){
            XWPFTableRow row =table.createRow();
//            XWPFTableRow row = table.insertNewTableRow(headCount[nowTableIndex]+1);
            //创建行,根据第一行创建的,导致表头合并单位格影响了列数
            List<XWPFTableCell> cells = row.getTableCells();
            int minusCell = cellsCount[nowTableIndex]-cells.size();
            for (int j = 0; j < minusCell; j++) {
                row.addNewTableCell();
            }
            //行属性复制
            row.getCtRow().setTrPr(modelRow.getCtRow().getTrPr());
            cells = row.getTableCells();
            for (int i1 = 0; i1 < cells.size(); i1++) {
                XWPFTableCell modelCell = modelRow.getCell(i1);
                //列属性复制
                cells.get(i1).getCTTc().setTcPr(modelCell.getCTTc().getTcPr());
                //段落属性复制
                if(modelCell.getParagraphs()!=null&&modelCell.getParagraphs().size()>0){
                    cells.get(i1).getParagraphs().get(0).getCTP().setPPr(modelCell.getParagraphs().get(0).getCTP().getPPr());
                }
            }
        }
        //遍历表格插入数据
        List<XWPFTableRow> rows = table.getRows();

        int contentIndex = 0;
        for(int i = headCount[nowTableIndex]; i < rows.size(); i++,contentIndex++){
            XWPFTableRow newRow = table.getRow(i);
            List<XWPFTableCell> cells = newRow.getTableCells();
            for(int j = 0; j < cells.size(); j++){
                XWPFTableCell cell = cells.get(j);
                try{
                    cell.setText(tableList.get(contentIndex).get(j));
                }catch (Exception e){
                    log.info(contentIndex+":"+nowTableIndex+":"+rows.size()+":"+cells.size());
                }
            }
        }

    }



    /**
     * 判断文本中时候包含$
     * @param text 文本
     * @return 包含返回true,不包含返回false
     */
    public static boolean checkText(String text){
        boolean check  =  false;
        if(text.indexOf("$")!= -1){
            check = true;
        }
        return check;

    }

    /**
     * 匹配传入信息集合与模板
     * @param value 模板需要替换的区域
     * @param textMap 传入信息集合
     * @return 模板需要替换区域信息集合对应值
     */
    public static String changeValue(String value, Map<String, String> textMap){
        Set<Entry<String, String>> textSets = textMap.entrySet();
        for (Entry<String, String> textSet : textSets) {
            //匹配模板与替换值 格式${key}
            String key = "${"+textSet.getKey()+"}";
            if(value.indexOf(key)!= -1){
                value = textSet.getValue();
            }
        }
        //模板未匹配到区域替换为空
        if(checkText(value)){
            value = "";
        }
        return value;
    }

}

测试代码

public static void main(String[] args) {
        //模板文件地址
        String inputUrl = "D:\\tmp\\word\\平台简报模板.docx";
        //新生产的模板文件
        Random random = new Random();
        String outputUrl = "D:\\tmp\\word\\test"+random.nextInt(20)+".docx";

        Map<String, String> testMap = new HashMap<String, String>();
        testMap.put("title", "要替换的title");
        testMap.put("describe", "要替换的describe");

        List<List<List<String>>> testList = new ArrayList<>();
		
		//表格一
        {
			List<List<String>> rows = new ArrayList<>();
			List<String> cells = new ArrayList<>();
			cells.add("1");
			cells.add("companyName");
			cells.add("1");
			cells.add("33");
			cells.add("23");
			cells.add("98");
			cells.add("23");
			cells.add("27");

			rows.add(cells);  //第一行数据

			cells = new ArrayList<>();
			cells.add("2");
			cells.add("companyName2");
			cells.add("1");
			cells.add("31");
			cells.add("23");
			cells.add("96");
			cells.add("23");
			cells.add("20");

			rows.add(cells);  //第二行数据

			testList.add(rows);
		}
		
		//表格二
        {
			List<List<String>> rows = new ArrayList<>();
			List<String> cells = new ArrayList<>();
			cells.add("1");
			cells.add("companyName");
			cells.add("1");
			cells.add("33");
			cells.add("23");
			cells.add("98");
			cells.add("23");
			cells.add("27");

			rows.add(cells);  //第一行数据

			cells = new ArrayList<>();
			cells.add("2");
			cells.add("companyName2");
			cells.add("1");
			cells.add("31");
			cells.add("23");
			cells.add("96");
			cells.add("23");
			cells.add("20");

			rows.add(cells);  //第二行数据

			testList.add(rows);
		}
		


        WordToNewWordUtils.changWord(inputUrl, outputUrl, testMap, testList);
    }

 

可以用map中的key匹配替换${key} 中内容;

可以获取模板中设置的字号,对齐方式等,这样就是完全往里面填充数据,不需要关注字号,对齐方式了,就沿用模板中设置的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值