java根据模板动态生成word文档

模板文档

首先,需要创建一个word模板,我的模板例子如下:
在这里插入图片描述

动态生成的文档

根据java代码动态的修改模板生成自己想要的文档,结果如下:
在这里插入图片描述

具体代码

代码操作如下:其中进行了文本的替换,图片的插入,以及表格的操作。

引入依赖

		<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>

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

java代码

工具类FileUtil,OfficeUtil,CustomXWPFDocument的下载
提取码: x9dd
注:CustomXWPFDocument是继承XWPFDocument的重写的工具类

@RestController
@CrossOrigin
@RequestMapping("Download")
@Slf4j
public class DownloadWordController {

    @RequestMapping("Word")
    @ResponseBody
    public ResponseEntity<ByteArrayResource> downLoadReport(HttpServletRequest request, HttpServletResponse response) {
        try {
            String img1="D://file//图片1.png";

            //复制模板1给模板2,之后操作模板2,为了防止模板1的变动,之后动态修改模板2
            FileUtil.fileChannelCopy("D://file//模板1.docx", "D://file//模板2.docx");

            Map<String,Object> param = new HashMap<String, Object>();
            param.put("Hi", "你好!");
            param.put("Welcome", "欢迎!");

            /*指定模板位置pg_gyscpzlgksppg的位置替换为图片
            Map<String,Object> header = new HashMap<String, Object>();
            header.put("width", 100);
            header.put("height", 100);
            header.put("type", "png");
            header.put("content", image2Bytes("D:\\test\\upload\\img\\a.png"));
            param.put("我的图片",header);*/


            //根据工具类将param中的要替换的内容替换到模板2中
            CustomXWPFDocument doc = OfficeUtil.generateWord(param, "D://file//模板2.docx");

            //遍历word文档的所有段落,向指定位置添加图片和操作指定表格
            for (XWPFParagraph p : doc.getParagraphs()) {
                List<XWPFRun> runs = p.getRuns();
                if (runs != null) {
                    for (XWPFRun r : runs) {
                        //需要替换的文本
                        String text = "图片1";
                        String tableName = "我的表格";
                        String text2 = r.getText(0);

                        //向指定位置添加图片
                        if (text != null && text2 != null && text2.contains(text)) {
                            //从0开始替换文本为“”
                            r.setText("图片1如下:", 0);
                            r.addBreak();//换行
                            r.setText("                  ");
                            //设置图片(图片流,图片格式,图片名称,图片宽,图片高)
                            r.addPicture(new FileInputStream(img1), XWPFDocument.PICTURE_TYPE_PNG, new File(img1).getName(), Units.toEMU(200), Units.toEMU(100));
                            r.addBreak();//换行
                            r.setText("                                 图片1");
                            r.addBreak();//换行
                            r.setText(" ");
                        }

                        //操作指定表格
                        if (text2 != null && text2.contains(tableName)) {
                            //获取模板中的第1个表格
                            XWPFTable table = doc.getTables().get(0);
                            //给此表格添加三行
                            addRows(table, 2, 3);
                            //删除第2行和第3行原有的的第一个单元格的第一段数据
                            //table.getRow(1).getCell(0).removeParagraph(0);
                            //table.getRow(2).getCell(0).removeParagraph(0);

                            //开始为表格添加数据
                            for (int i = 1; i <= 5; i++) {
                                XWPFTableRow row = table.getRow(i);
                                int index=0;
                                row.getCell(index).removeParagraph(0);
                                row.getCell(index++).setText(String.valueOf(i));//设置序号
                                row.getCell(index++).setText("五年2班");//设置班级
                                row.getCell(index++).setText("李雷");//设置姓名
                                row.getCell(index++).setText("90");//设置语文
                                row.getCell(index++).setText("95");//设置数学
                            }

                            //合并单元格
                            mergeCellsVertically(table, 1, 1, 5);
                        }
                    }
                }
            }
            //将修改后的模板2文档写入最终文档final.docx
            FileOutputStream fopts = new FileOutputStream("D:\\test\\wordFile\\final.docx");
            doc.write(fopts);
            fopts.close();
            doc.close();

            //设备供应商
            String fileName = "最终文档";
            File file = new File("D:\\test\\wordFile\\final.docx");
            ByteArrayResource resource = new ByteArrayResource(Files.readAllBytes(Paths.get(file.getAbsolutePath())));
            return ResponseEntity.ok().header("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".docx", "UTF-8"))
                    .header("FileName", URLEncoder.encode(fileName + ".docx", "UTF-8"))
                    .header("Access-Control-Expose-Headers", "FileName")
                    .contentLength(file.length()).contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"))
                    .body(resource);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * author:wangzhiming
     * date:2022-01-18
     * des:表末尾添加行(表下标,要复制样式的行,添加行数),此方法先添加行之后再操作表格较好
     * @param table
     * @param source
     * @param rows
     */
    public void addRows(XWPFTable table, int source, int rows){
        try{
            int index = table.getNumberOfRows();
            for(int i=1;i<=rows;i++) {
                XWPFTableRow sourceRow = table.getRow(source);
                XWPFTableRow targetRow = table.insertNewTableRow(index++);
                targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
                List<XWPFTableCell> sourceCells = sourceRow.getTableCells();
                for (XWPFTableCell sourceCell : sourceCells) {
                    XWPFTableCell newCell = targetRow.addNewTableCell();
                    newCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());
                    List<XWPFParagraph> sourceParagraphs = sourceCell.getParagraphs();
                    if (StringUtils.isEmpty(sourceCell.getText())) {
                        continue;
                    }

                    XWPFParagraph sourceParagraph = sourceParagraphs.get(0);
                    List<XWPFParagraph> targetParagraphs = newCell.getParagraphs();
                    if (StringUtils.isEmpty(newCell.getText())) {
                        XWPFParagraph ph = newCell.addParagraph();
                        ph.getCTP().setPPr(sourceParagraph.getCTP().getPPr());
                        XWPFRun run = ph.getRuns().isEmpty() ? ph.createRun() : ph.getRuns().get(0);
                        if(sourceParagraph.getRuns().size()>0)
                            run.setFontFamily(sourceParagraph.getRuns().get(0).getFontFamily());
                    } else {
                        XWPFParagraph ph = targetParagraphs.get(0);
                        ph.getCTP().setPPr(sourceParagraph.getCTP().getPPr());
                        XWPFRun run = ph.getRuns().isEmpty() ? ph.createRun() : ph.getRuns().get(0);
                        if(sourceParagraph.getRuns().size()>0)
                            run.setFontFamily(sourceParagraph.getRuns().get(0).getFontFamily());
                    }
                }
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
    }

    /**
     * author:wangzhiming
     * date:2022-01-18
     * des:word跨行并单元格(表,合并哪一列,开始合并的行,合并结束的行)
     * @param table
     * @param col
     * @param fromRow
     * @param toRow
     */
    public void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
        /*for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
            if ( rowIndex == fromRow ) {
                // The first merged cell is set with RESTART merge value
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
            } else {
                // Cells which join (merge) the first one, are set with CONTINUE
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }


        }*/

        for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++)
        {
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);

            CTTc ctTc = cell.getCTTc();
            if (ctTc.getTcPr() == null)
            {
                ctTc.addNewTcPr();
            }

            //第一个合并单元格用重启合并值设置
            if (rowIndex == fromRow)
            {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
            }
            else
            {
                //合并第一个单元格的单元被设置为“继续”
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }

        }
    }
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值