精华内容
下载资源
问答
  • poi替换word内容
    2022-05-18 18:43:48

    param的k为word模板中要替换的占位符,v为要替换成的文字

    本文的占位符为${} 可自行修改替换

    //替换word中的占位符
        private void replaceWordText(List<XWPFParagraph> paragraphList, Map<String, Object> param) {
            for (XWPFParagraph paragraph : paragraphList) {
                // 遍历获取段落中所有的runs
                List<XWPFRun> runs = paragraph.getRuns();
                // 合并逻辑
                for (int i = 0; i < runs.size(); i++) {
                    //获取字符
                    String text0 = runs.get(i).getText(runs.get(i).getTextPosition());
                    if (text0 != null && text0.contains("$")) {
                        //包含占位符的字符缓存
                        StringBuilder cache = new StringBuilder(text0);
                        //记录run结束的角标,开始的角标为i
                        int endIndex = 0;
                        boolean contains = text0.contains("}");
                        //同一个run中是否包含完成占位符
                        if (!contains) {
                            int j = i + 1 ;
                            for (; j < runs.size(); j++) {
                                String text1 = runs.get(j).getText(runs.get(j).getTextPosition());
                                if (text1 == null) {
                                    continue;
                                }
                                cache.append(text1);
                                if (text1.contains("}")) {
                                    endIndex = j;
                                    break;
                                }
                            }
                        }
                        if (contains || endIndex != 0) {
                            //处理替换
                            String s = cache.toString();
                            for (Map.Entry<String, Object> entry : param.entrySet()) {
                                String k = entry.getKey();
                                String v = entry.getValue().toString();
                                if (s.contains(k)) {
                                    log.info("替换字符串:{} -> {}", k, v);
                                    String replace = s.replace(k, v);
                                    runs.get(i).setText(replace, 0);
                                    for (int j = endIndex; j > i; j--) {
                                        //角标移除后,runs会同步变动,直接继续处理i就可以
                                        log.info("移除下标:{}", j);
                                        paragraph.removeRun(j);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

    更多相关内容
  • poi替换word内容

    千次阅读 2022-03-16 14:19:14
    poi插入表格 poi插入图片 poi插入文本

    都是通过占位符实现的,test方法改成工具类,传入参数就可以直接用了

    需要的jar

            <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>4.1.2</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>4.1.2</version>
            </dependency>
    

    替换文本

        @Test
        public void testInsertText() throws Exception {
            //获取时间
            Calendar cal = Calendar.getInstance();
            int day = cal.get(Calendar.DATE);
            int month = cal.get(Calendar.MONTH) + 1;
            int year = cal.get(Calendar.YEAR);
            int dow = cal.get(Calendar.DAY_OF_WEEK);
            int dom = cal.get(Calendar.DAY_OF_MONTH);
            int doy = cal.get(Calendar.DAY_OF_YEAR);
    
            //要替换的map,key为占位符,value为要被替换的值
            Map<String, Object> map = new HashMap<>();
            map.put("${company}", "金马投资公司");
            map.put("${name}", "陈玉");
            map.put("${idNumber}", "642152152542151254");
            map.put("${phone}", "13358445878");
            map.put("${address}", "北京市顺义区张家巷14号");
            map.put("${year}", year);
            map.put("${month}", month);
            map.put("${day}", day);
            map.put("${agent}", "张律师");
    
            //读取文件
            OPCPackage opcPackage = POIXMLDocument.openPackage("D:\\期货委托合同.docx");
            //加载文档
            XWPFDocument doc = new XWPFDocument(opcPackage);
            //获取所有段落
            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, Object> 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);
                        }
                    }
    
                }
            }
            File file = new File("D:\\期货委托合同1.docx");
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            doc.write(fileOutputStream);
        }
    

    ${name}没成功是因为我直接在word里面手动输入的,没有被识别为一个文本对象,在其它地方写好${name},然后复制到word中
    在这里插入图片描述

    插入table

        @Test
        public void testInserTable1() throws Exception {
    
    		//初始化一些数据
    		//表头
            List<String> row1 = new ArrayList<>();
            row1.add("时间");
            row1.add("数量");
            row1.add("类型");
            //数据
            List<String> row2 = new ArrayList<>();
            row2.add("3-15");
            row2.add("1");
            row2.add("A");
            List<String> row3 = new ArrayList<>();
            row3.add("3-16");
            row3.add("3");
            row3.add("B");
            //数据List<List<String>>存储,只存数据,不存表头
            List<List<String>> rowData = new ArrayList<>();
            rowData.add(row2);
            rowData.add(row3);
    
            //读取文件
            OPCPackage opcPackage = POIXMLDocument.openPackage("D:\\test.docx");
            //加载文档
            XWPFDocument doc = new XWPFDocument(opcPackage);
            //获取所有段落
            List<XWPFParagraph> paragraphList = doc.getParagraphs();
            //遍历段落
            for (int p=0;p<paragraphList.size();p++) {
            	//获取当前段落的所有文本对象
                List<XWPFRun> runs = paragraphList.get(p).getRuns();
                //遍历文本对象
                for (int r=0;r<runs.size();r++) {
    				//获取文本对象的值
                    String text = runs.get(r).getText(0);
    
                    if (text!=null){
                    	//判断有没有和占位符相同的,如果有
                        if(text.indexOf("${table1}")>=0){
    
                            //获取光标
                            XmlCursor cursor = paragraphList.get(p).getCTP().newCursor();
                            //插入新表格
                            XWPFTable newTable = doc.insertNewTbl(cursor);
                            //设置格式
                            CTTblPr tblPr = newTable.getCTTbl().getTblPr();
                            tblPr.getTblW().setType(STTblWidth.DXA);
                            tblPr.getTblW().setW(new BigInteger("10000"));
    
                            //创建好的表格默认有一个单元格,直接赋值
                            newTable.getRow(0).getCell(0).setText(row1.get(0));
                            //设置第一行剩下的值
                            for (int i=1;i<row1.size();i++){
                                newTable.getRow(0).createCell().setText(row1.get(i));
                            }
    
                            //创建row,rowData.size()判断有几行
                            for (int i=0;i<rowData.size();i++){
                                //创建row
                                XWPFTableRow row = newTable.createRow();
                                //拿到第一行数据,判断有几列,然后逐列插入单元格的值
                                for (int j=0;j<rowData.get(0).size();j++){
                                    row.getCell(j).setText(rowData.get(i).get(j));
                                }
                            }
                            //删除旧的文本对象,就是删除占位符
                            paragraphList.get(p).removeRun(0);
                        }
                    }
                }
            }
            doc.write(new FileOutputStream("D:\\test1.docx"));
        }
    

    在这里插入图片描述

    插入图片

        @Test
        public void insertImage() throws Exception {
            //读取文件
            OPCPackage opcPackage = POIXMLDocument.openPackage("D:\\test.docx");
            //加载文档
            XWPFDocument doc = new XWPFDocument(opcPackage);
            //获取所有段落
            List<XWPFParagraph> paragraphList = doc.getParagraphs();
            //遍历段落
            for (int p = 0; p < paragraphList.size(); p++) {
                //获取所有文本对象
                List<XWPFRun> runs = paragraphList.get(p).getRuns();
                //遍历所有文本对象
                for (int r = 0; r < runs.size(); r++) {
                    String text = runs.get(r).getText(0);
                    if (text != null) {
                        //判断文本对象是否包含图片占位符
                        if (text.indexOf("${pic1}") >= 0) {
                            //换行
                            runs.get(r).addBreak();
                            String picPath="D:\\pic.png";
                            runs.get(r).addPicture(new FileInputStream(picPath),Document.PICTURE_TYPE_PNG,picPath, Units.toEMU(450),Units.toEMU(300));
                            runs.get(r).addBreak(BreakType.TEXT_WRAPPING);
                            //删除旧的文本对象,就是删除占位符
                            //paragraphList.get(p).removeRun(0);
                            //插入图片后,图片和占位符变成一个文本对象了,removeRun连图片一起删了,使用setText
                            runs.get(r).setText("",0);
    
                        }
                    }
                }
            }
            doc.write(new FileOutputStream("D:\\test1.docx"));
        }
    

    在这里插入图片描述

    遇到问题

    使用${}字符内容被分割

    使用${name}占位替换文字,解析发现被分割成了如下
    在这里插入图片描述
    ,导致无法替换,解决方法:在其它地方写好${name},然后复制到word中,再次查看
    在这里插入图片描述

    代码和docx模板

    需要全代码示例和模板的私聊

    展开全文
  • 使用poi替换word中的图片,无需加书签,doc/docx均可,亲测。
  • 通过POI可实现根据word模板替换文中或者表格的关键字(包括给定表头动态追加表格)。业务需求我是在模板中直接插入图片(例如衬于文字下方),所有代码中没有插入图片代码。
  • poi替换word模板内容

    2021-10-08 18:58:37
    -- poi --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.0.0</version> </dependency> <dependency> ...

    pom.xml

    <!-- poi -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>4.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>4.0.1</version>
    </dependency>
    

    ChartDataDTO

    package com.example.all;
    
    import lombok.Data;
    
    /**
     * ChartDataDTO.
     *
     * @author : ljl
     * @Date: 2021-10-08 15:42
     * @Version: 1.0.0
     **/
    @Data
    public class ChartDataDTO {
    
        private Integer number1;
        private Integer number2;
    
    }
    

    PoiWordTools(刷新图表的方法)

    package com.example.all;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.math.BigDecimal;
    import java.util.List;
    import java.util.Map;
    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.openxmlformats.schemas.drawingml.x2006.chart.*;
    
    /**
     * poi生成word的工具类
     */
    public class PoiWordTools {
    
        /**
         * 替换图表
         * @param poixmlDocumentPart
         * @param titleArr 内置excel第一行内容,如系列、系列1、系列2
         * @param fldNameArr item集合,item1、item2...
         * @param listItemsByType 数据集合,内部元素是map,对应(item1, xx),(item2,xx)...
         * @param chartTypes 0:柱状图;1:折线图;2:饼图;3:雷达图;4:散点图;
         */
        public static void replaceCharts(POIXMLDocumentPart poixmlDocumentPart, List<String> titleArr, List<String> fldNameArr,
                                         List<Map<String, String>> listItemsByType, List<Integer> chartTypes) {
            for (Integer chartType : chartTypes) {
                XWPFChart chart = (XWPFChart) poixmlDocumentPart;
                chart.getCTChart();
                // 根据属性第一列名称切换数据类型
                CTChart ctChart = chart.getCTChart();
                CTPlotArea plotArea = ctChart.getPlotArea();
                switch (chartType) {
                    case 0:
                        CTBarChart ctBarChart = plotArea.getBarChartArray(0);
                        List<CTBarSer> ctBarSers = ctBarChart.getSerList();
                        refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
                        refreshStrGraphContent(ctBarChart, ctBarSers, listItemsByType, fldNameArr, 1, chartType);
                        break;
                    case 1:
                        CTLineChart lineChartArray = plotArea.getLineChartArray(0);
                        List<CTLineSer> ctLineSers = lineChartArray.getSerList();
                        refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
                        refreshStrGraphContent(lineChartArray, ctLineSers, listItemsByType, fldNameArr, 1, chartType);
                        break;
                    case 2:
                        CTPieChart pieChartArray = plotArea.getPieChartArray(0);
                        List<CTPieSer> ctPieSers = pieChartArray.getSerList();
                        refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
                        refreshStrGraphContent(pieChartArray, ctPieSers, listItemsByType, fldNameArr, 1, chartType);
                        break;
                    case 3:
                        CTRadarChart ctRadarChart = plotArea.getRadarChartArray(0);
                        List<CTRadarSer> ctRadarSers = ctRadarChart.getSerList();
                        refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
                        refreshStrGraphContent(ctRadarChart, ctRadarSers, listItemsByType, fldNameArr, 1, chartType);
                        break;
                    case 4:
                        CTScatterChart ctScatterChart = plotArea.getScatterChartArray(0);
                        List<CTScatterSer> ctScatterSers = ctScatterChart.getSerList();
                        refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
                        refreshStrGraphContent(ctScatterChart, ctScatterSers, listItemsByType, fldNameArr, 1, chartType);
                        break;
                    default:
                        break;
                }
            }
        }
    
        /**
         * 刷新内置excel数据
         * @param chart
         * @param dataList 数据集合,内部元素是map,对应(item1, xx),(item2,xx)...
         * @param fldNameArr item集合,item1、item2...
         * @param titleArr 内置excel第一行内容,如系列、系列1、系列2
         * @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++) {
                    // i+1是跳过第一行标题行
                    int rowIndex = i + 1;
                    if (sheet.getRow(rowIndex) == null) {
                        if (j == 0) {
                            try {
                                sheet.createRow(rowIndex).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(rowIndex).createCell(j).setCellValue("");
                                } else {
                                    sheet.createRow(rowIndex).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(rowIndex).createCell(j);
                        } else {
                            sheet.getRow(rowIndex).createCell(j).setCellValue(b.doubleValue());
                        }
                    }
                }
    
            }
            // 更新嵌入的workbook
            POIXMLDocumentPart xlsPart = chart.getRelations().get(0);
            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;
                    }
                }
            }
            return result;
        }
    
        /**
         * 刷新图表数据
         * @param typeChart
         * @param serList
         * @param dataList 据集合,内部元素是map,对应(item1, xx),(item2,xx)...
         * @param fldNameArr item集合,item1、item2...
         * @param position
         * @param chartType 0:柱状图;1:折线图;2:饼图;3:雷达图;4:散点图;
         * @return
         */
        public static boolean refreshStrGraphContent(Object typeChart, List<?> serList, List<Map<String, String>> dataList,
                                                     List<String> fldNameArr, int position, Integer chartType) {
            boolean result = true;
            // 更新数据区域
            for (int i = 0; i < serList.size(); i++) {
                // CTSerTx tx=null;
                CTAxDataSource cat = null;
                CTNumDataSource val = null;
                switch (chartType) {
                    case 0:
                        CTBarSer ctBarSer = ((CTBarChart) typeChart).getSerArray(i);
                        cat = ctBarSer.getCat();
                        val = ctBarSer.getVal();
                        break;
                    case 1:
                        CTLineSer ctLineSer = ((CTLineChart) typeChart).getSerArray(i);
                        cat = ctLineSer.getCat();
                        val = ctLineSer.getVal();
                        break;
                    case 2:
                        CTPieSer ctPieSer = ((CTPieChart) typeChart).getSerArray(i);
                        cat = ctPieSer.getCat();
                        val = ctPieSer.getVal();
                        break;
                    case 3:
                        CTRadarSer ctRadarSer = ((CTRadarChart) typeChart).getSerArray(i);
                        cat = ctRadarSer.getCat();
                        val = ctRadarSer.getVal();
                        break;
                    case 4:
                        CTScatterSer ctScatterSer = ((CTScatterChart) typeChart).getSerArray(i);
                        cat = ctScatterSer.getXVal();
                        val = ctScatterSer.getYVal();
                        break;
                    default:
                        break;
                }
                // strData.set
                CTStrData strData = cat.getStrRef().getStrCache();
                CTNumData numData = val.getNumRef().getNumCache();
                // unset old axis text
                strData.setPtArray((CTStrVal[]) null);
                // unset old values
                numData.setPtArray((CTNumVal[]) null);
                // set model
                long 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;
        }
    
    }
    
    

    PoiDemo(替换特定字符串、补全表格、更新图表)

    package com.example.all;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.math.BigInteger;
    import java.util.*;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.poi.ooxml.POIXMLDocument;
    import org.apache.poi.ooxml.POIXMLDocumentPart;
    import org.apache.poi.xwpf.usermodel.*;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
    
    /**
     * PoiDemo.
     *
     * @author : ljl
     * @Date: 2021-10-08 13:34
     * @Version: 1.0.0
     **/
    @Slf4j
    public class PoiDemo {
    
        public static String REPLACE_SIGN = "$";
    
        public static void main(String[] args) throws IOException {
            String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
            String inputUrl = path.substring(0, path.lastIndexOf("target")) + "src/main/resources/省市旅行社行业监测周报模板.docx";
            XWPFDocument xwpfDocument = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
            HashMap<String, String> textMap = new HashMap<>();
            textMap.put("${contentSynopsis1}", "text1");
            textMap.put("${contentSynopsis12}", "text2");
            textMap.put("${text3}", "text3");
            textMap.put("${text4}", "text4");
            textMap.put("${table1}", "table1");
            textMap.put("${table2}", "table2");
            textMap.put("${table3}", "table3");
            textMap.put("${table4}", "table4");
            // 解析替换段落对象
            changeText(xwpfDocument, textMap);
            // 解析替换表格对象
            List<List<String[]>> tableList = new ArrayList<>();
            changeTable(xwpfDocument, textMap, tableList);
            // 解析替换图表
            // 图表的准备阶段
            // 获取word模板中的所有图表元素,用map存放
            // 为什么不用list保存:查看doc.getRelations()的源码可知,源码中使用了hashMap读取文档图表元素,
            // 对relations变量进行打印后发现,图表顺序和文档中的顺序不一致,也就是说relations的图表顺序不是文档中从上到下的顺序
            // 图表内编辑的excel第一行标题行必须都有内容,如:系列 系列1 系列2,下面的行可以有数据,会被替换不影响结果
            Map<String, POIXMLDocumentPart> chartsMap = new HashMap<>();
            //动态刷新图表
            List<POIXMLDocumentPart> relations = xwpfDocument.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);
                }
            }
            log.info("图表数量:" + chartsMap.size() + "\n");
            // 替换第一个图标
            ChartDataDTO chartDataDTO1 = new ChartDataDTO();
            chartDataDTO1.setNumber1(10);
            chartDataDTO1.setNumber2(305);
            ChartDataDTO chartDataDTO2 = new ChartDataDTO();
            chartDataDTO2.setNumber1(200);
            chartDataDTO2.setNumber2(300);
            ChartDataDTO chartDataDTO3 = new ChartDataDTO();
            chartDataDTO3.setNumber1(150);
            chartDataDTO3.setNumber2(100);
            ArrayList<ChartDataDTO> chartDataDTOS = new ArrayList<>();
            chartDataDTOS.add(chartDataDTO1);
            chartDataDTOS.add(chartDataDTO2);
            chartDataDTOS.add(chartDataDTO3);
            doCharts1(chartsMap.get("/word/charts/chart1.xml"), chartDataDTOS);
            // 生成报告
            String resultPath = path.substring(0, path.lastIndexOf("target")) + "src/main/resources/省市旅行社行业监测周报.docx";
            File file = new File(resultPath);
            if (file.exists()) {
                file.delete();
            }
            FileOutputStream output = new FileOutputStream(resultPath);
            xwpfDocument.write(output);
            // 千万不可使用document.close(),会在原模板上进行改动
            output.close();
        }
    
        /**
         * 替换段落、表格内的文本,将文本内的'${xx}'替换为对应目标值
         * @param document docx解析对象
         * @param textMap 需要替换的信息集合
         */
        public static void changeText(XWPFDocument document, Map<String, String> textMap){
            // 替换段落内的文本信息
            List<XWPFParagraph> documentParagraphs = document.getParagraphs();
            for (XWPFParagraph xwpfParagraph : documentParagraphs) {
                replaceParagraph(xwpfParagraph, textMap);
            }
            // 替换表格内的文本信息
            List<XWPFTable> documentTables = document.getTables();
            for (XWPFTable xwpfTable : documentTables) {
                List<XWPFTableRow> xwpfTableRows = xwpfTable.getRows();
                for (XWPFTableRow xwpfTableRow : xwpfTableRows) {
                    List<XWPFTableCell> xwpfTableRowTableCells = xwpfTableRow.getTableCells();
                    for (XWPFTableCell xwpfTableCell : xwpfTableRowTableCells) {
                        String cellText = xwpfTableCell.getText();
                        // 判断单元格是否需要替换
                        if(checkText(cellText)) {
                            List<XWPFParagraph> cellParagraphs = xwpfTableCell.getParagraphs();
                            for (XWPFParagraph xwpfParagraph : cellParagraphs) {
                                replaceParagraph(xwpfParagraph, textMap);
                            }
                        }
                    }
                }
            }
        }
    
        /**
         * 判断文本中时候包含$
         * @param text 文本
         * @return 包含返回true,不包含返回false
         */
        public static boolean checkText(String text){
            boolean check  =  false;
            if(text.indexOf(REPLACE_SIGN)!= -1){
                check = true;
            }
            return check;
        }
    
        /**
         * 替换文本信息
         * @param paragraph 段落
         * @param textMap 需要替换的信息集合
         * @return 包含返回true,不包含返回false
         */
        public static void replaceParagraph(XWPFParagraph paragraph, Map<String, String> textMap){
            String text = paragraph.getText();
            while (checkText(text)) {
                int start = text.indexOf("$");
                int end = text.indexOf("}") + 1;
                String replaceStr = text.substring(start, end);
                String resultStr = textMap.getOrDefault(replaceStr, "");
                text = text.replace(replaceStr, resultStr);
                List<XWPFRun> runs = paragraph.getRuns();
                // 获取段落文本格式
                String fontFamily = runs.get(0).getFontFamily();
                int fontSize = runs.get(0).getFontSize();
                boolean bold = runs.get(0).isBold();
                UnderlinePatterns underline = runs.get(0).getUnderline();
                String underlineColor = runs.get(0).getUnderlineColor();
                while (!runs.isEmpty()) {
                    paragraph.removeRun(0);
                }
                XWPFRun run = paragraph.createRun();
                run.setText(text);
                run.setFontSize(fontSize);
                run.setFontFamily(fontFamily);
                run.setBold(bold);
                run.setUnderline(underline);
                run.setUnderlineColor(underlineColor);
            }
        }
    
        /**
         * 替换表格对象方法
         * @param document docx解析对象
         * @param textMap 需要替换的信息集合
         * @param tableList 需要插入的表格信息集合
         */
        public static void changeTable(XWPFDocument document, Map<String, String> textMap,
                                       List<List<String[]>> tableList){
            // 获取表格对象集合
            List<XWPFTable> tables = document.getTables();
            int size = tables.size();
            // 虽然应该严格传入对应的表格数量,但是此处还是对tableList进行了空补全
            while (tableList.size() < size) {
                tableList.add(new ArrayList<>());
            }
            for (int i = 0; i < size; i++) {
                // 只处理行数大于等于2的表格,且不循环表头
                XWPFTable table = tables.get(i);
                // 插入剩余的数据
                insertTable(table, tableList.get(i));
            }
        }
    
        /**
         * 为表格插入数据,行数不够添加新行
         * @param table 需要插入数据的表格
         * @param tableList 插入数据集合
         */
        public static void insertTable(XWPFTable table, List<String[]> tableList){
            if (tableList.isEmpty()) {
                return;
            }
            CTTblBorders borders = table.getCTTbl().getTblPr().addNewTblBorders();
            CTBorder hBorder = borders.addNewInsideH();
            hBorder.setVal(STBorder.Enum.forString("single"));
            hBorder.setSz(new BigInteger("1"));
            hBorder.setColor("000000");
    
            CTBorder vBorder = borders.addNewInsideV();
            vBorder.setVal(STBorder.Enum.forString("single"));
            vBorder.setSz(new BigInteger("1"));
            vBorder.setColor("000000");
    
            CTBorder lBorder = borders.addNewLeft();
            lBorder.setVal(STBorder.Enum.forString("single"));
            lBorder.setSz(new BigInteger("1"));
            lBorder.setColor("000000");
    
            CTBorder rBorder = borders.addNewRight();
            rBorder.setVal(STBorder.Enum.forString("single"));
            rBorder.setSz(new BigInteger("1"));
            rBorder.setColor("000000");
    
            CTBorder tBorder = borders.addNewTop();
            tBorder.setVal(STBorder.Enum.forString("single"));
            tBorder.setSz(new BigInteger("1"));
            tBorder.setColor("000000");
    
            CTBorder bBorder = borders.addNewBottom();
            bBorder.setVal(STBorder.Enum.forString("single"));
            bBorder.setSz(new BigInteger("1"));
            bBorder.setColor("000000");
    
            // 创建行,根据需要插入的数据添加新行,不处理表头
            int nowRowSize = table.getRows().size();
            for(int i = 0; i < tableList.size(); i++){
                XWPFTableRow row = table.createRow();
                List<XWPFTableCell> tableCells = row.getTableCells();
                while (tableCells.size() != tableList.get(0).length){
                    row.createCell();
                }
            }
    
            // 遍历表格插入数据
            List<XWPFTableRow> rows = table.getRows();
            XWPFRun xwpfRun = rows.get(0).getTableCells().get(0).getParagraphs().get(0).getRuns().get(0);
            String fontFamily = xwpfRun.getFontFamily();
            int fontSize = xwpfRun.getFontSize();
            for(int i = nowRowSize; i < rows.size(); i++) {
                XWPFTableRow newRow = table.getRow(i);
                String[] strings = tableList.get(i - nowRowSize);
                List<XWPFTableCell> cells = newRow.getTableCells();
                for(int j = 0; j < cells.size(); j++){
                    XWPFTableCell cell = cells.get(j);
                    XWPFParagraph paragraphArray = cell.getParagraphArray(0);
                    paragraphArray.setAlignment(ParagraphAlignment.CENTER);
                    XWPFRun run = paragraphArray.createRun();
                    run.setFontFamily(fontFamily);
                    run.setFontSize(fontSize);
                    run.setText(strings[j]);
                }
            }
        }
    
        public static void doCharts1(POIXMLDocumentPart poixmlDocumentPart, List<ChartDataDTO> chartDataDTOS) {
            // 数据准备
            // 标题
            List<String> titleArr = new ArrayList<>();
            titleArr.add("日期");
            titleArr.add("男");
            titleArr.add("女");
            titleArr.add("阴阳人");
    
            // 字段名(固定的,对应titleArr的size)
            List<String> fldNameArr = new ArrayList<>();
            fldNameArr.add("item1");
            fldNameArr.add("item2");
            fldNameArr.add("item3");
            fldNameArr.add("item4");
    
            // 数据集合
            List<Map<String, String>> listItemsByType = new ArrayList<>();
    
            ChartDataDTO chartDataDTO1 = chartDataDTOS.get(0);
            ChartDataDTO chartDataDTO2 = chartDataDTOS.get(1);
            ChartDataDTO chartDataDTO3 = chartDataDTOS.get(2);
    
            Map<String, String> base1 = new HashMap<>();
            base1.put("item1", "第一天");
            base1.put("item2", String.valueOf(chartDataDTO1.getNumber1()));
            base1.put("item3", String.valueOf(chartDataDTO2.getNumber1()));
            base1.put("item4", String.valueOf(chartDataDTO3.getNumber1()));
    
            Map<String, String> base2 = new HashMap<>();
            base2.put("item1", "第二天");
            base2.put("item2", String.valueOf(chartDataDTO1.getNumber2()));
            base2.put("item3", String.valueOf(chartDataDTO2.getNumber2()));
            base2.put("item4", String.valueOf(chartDataDTO3.getNumber2()));
    
            listItemsByType.add(base1);
            listItemsByType.add(base2);
    
            // 替换图标内容
            PoiWordTools.replaceCharts(poixmlDocumentPart, titleArr, fldNameArr, listItemsByType, Arrays.asList(1));
        }
        
    }
    
    
    展开全文
  • java 对word关键字替换,可替换word表格中的关键字,word转PDF
  • java poi 替换word文本

    2018-01-16 16:04:08
    java poi 实现word文本的替换,支持doc和docx格式的文本替换
  • 使用poiword读取后替换指定内容后再次生成新word,本人经过测试,拿来即用!
  • java poi替换word内容生成pdf文件

    万次阅读 热门讨论 2019-01-15 14:15:17
    替换word文档内容 package com.docx.test; import org.apache.poi.xwpf.usermodel.*; import org.junit.Test; import java.io.*; import java.util.HashMap; import java.util.Iterator; import java.util.List; ...

    替换word文档内容

    package com.docx.test;
    
    import org.apache.poi.xwpf.usermodel.*;
    import org.junit.Test;
    
    import java.io.*;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class DocxUnitl {
    
        /**
         * 用一个docx文档作为模板,然后替换其中的内容,再写入目标文档中。
         * @throws Exception
         */
        @Test
        public void testTemplateWrite() throws Exception {
    
            String pdfPath = "D:\\HHKJ\\project\\test\\lgwdha.pdf";
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("county", "桂林");
            params.put("time", "2019年1月15日");
            params.put("time2", "2019年1月16日");
            params.put("str", "具体整改要求,不管多少个字");
            params.put("time3", "2019年1月15日");
    
            String filePath = "D:\\HHKJ\\project\\test\\lgwdh.docx";
            InputStream is = new FileInputStream(filePath);
            XWPFDocument doc = new XWPFDocument(is);
            //替换段落里面的变量
            this.replaceInPara(doc, params);
            //替换表格里面的变量
    //        this.replaceInTable(doc, params);
            OutputStream os = new FileOutputStream("D:\\HHKJ\\project\\test\\lgwdha.docx");
            doc.write(os);
    
            this.close(os);
            this.close(is);
        }
    
    
    
    
        /**
         * 替换段落里面的变量
         * @param doc 要替换的文档
         * @param params 参数
         */
        private void replaceInPara(XWPFDocument doc, Map<String, Object> params) {
            Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
            XWPFParagraph para;
    
            while (iterator.hasNext()) {
                para = iterator.next();
    //            CTPPr pr = para.getCTP().getPPr();
                this.replaceInPara(para, params);
            }
        }
    
        /**
         * 替换段落里面的变量
         * @param para 要替换的段落
         * @param params 参数
         */
        private void replaceInPara(XWPFParagraph para, Map<String, Object> params) {
            List<XWPFRun> runs;
            Matcher matcher;
            if (this.matcher(para.getParagraphText()).find()) {
                runs = para.getRuns();
                System.out.println("2:"+runs);
                for (int i=0; i<runs.size(); i++) {
                    XWPFRun run = runs.get(i);
                    String runText = run.toString();
                    matcher = this.matcher(runText);
                    if (matcher.find()) {
                        while ((matcher = this.matcher(runText)).find()) {
                            runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));
                        }
                        //直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun,把文本附加在当前文本后面,
                        //所以我们不能直接设值,需要先删除当前run,然后再自己手动插入一个新的run。
    
                        run.setText(runText,0);
    //                    int fontSize = run.getFontSize();
    //                    String fontFamily = run.getFontFamily();
    //                    para.removeRun(i);
    //                    para.insertNewRun(i).setText(runText);
    //                    para.insertNewRun(i).setFontSize(fontSize);
    //                    para.insertNewRun(i).setFontFamily(fontFamily);
                    }
                }
            }
        }
    
        /**
         * 替换表格里面的变量
         * @param doc 要替换的文档
         * @param params 参数
         */
        private void replaceInTable(XWPFDocument doc, Map<String, Object> params) {
            Iterator<XWPFTable> iterator = doc.getTablesIterator();
            XWPFTable table;
            List<XWPFTableRow> rows;
            List<XWPFTableCell> cells;
            List<XWPFParagraph> paras;
            while (iterator.hasNext()) {
                table = iterator.next();
                rows = table.getRows();
                for (XWPFTableRow row : rows) {
                    cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        paras = cell.getParagraphs();
                        for (XWPFParagraph para : paras) {
                            this.replaceInPara(para, params);
                        }
                    }
                }
            }
        }
    
        /**
         * 正则匹配字符串
         * @param str
         * @return
         */
        private Matcher matcher(String str) {
            Pattern pattern = Pattern.compile("\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(str);
            return matcher;
        }
    
        /**
         * 关闭输入流
         * @param is
         */
        private void close(InputStream is) {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * 关闭输出流
         * @param os
         */
        private void close(OutputStream os) {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
    

    word转pdf

    package com.docx.test;
    
    import java.io.*;
    import org.apache.poi.xwpf.converter.pdf.PdfConverter;
    import org.apache.poi.xwpf.converter.pdf.PdfOptions;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    
    public class word2pdf {
    
        /**
         * @param args the command line arguments
         * @throws java.io.IOException
         */
        public static void main(String[] args) throws IOException {
            String docPath = "D:\\HHKJ\\project\\test\\lgwdha.docx";
            String pdfPath = "D:\\HHKJ\\project\\test\\lgwdha.pdf";
    
            XWPFDocument document;
            InputStream doc = new FileInputStream(docPath);
            document = new XWPFDocument(doc);
            PdfOptions options = PdfOptions.create();
            OutputStream out = new FileOutputStream(pdfPath);
            PdfConverter.getInstance().convert(document, out, options);
    
            doc.close();
            out.close();
        }
    
    }
    

    所需jar包

    dom4j-1.6.1-hudson-1.jar
    itext-4.2.0.jar
    itext-asian-5.2.0.jar
    itext-asiancmaps-5.1.1.jar
    itextpdf-5.4.0.jar
    jsoup-1.11.3.jar
    ooxml-schemas-1.1.jar
    org.apache.poi.xwpf.converter.core-1.0.4.jar
    org.apache.poi.xwpf.converter.pdf-1.0.4.jar
    xdocreport-2.0.1.jar
    xmlbeans-5.3.0-rc1.jar
    xmlgraphics-commons-2.2.jar

    poi-3.9-20121203.jar
    poi-examples-3.9-20121203.jar
    poi-excelant-3.9-20121203.jar
    poi-ooxml-3.9-20121203.jar
    poi-scratchpad-3.9-20121203.jar

    所遇问题

    1.java.lang.ClassNotFoundException: org/openxmlformats/schemas/wordprocessingml/x2006/main/FontsDocument$Factory
    原博地址:https://blog.csdn.net/lex1993/article/details/47062141
    解决办法:导入ooxml-schemas-1.1.jar这个包,去掉poi-ooxml-3.9-20121203.jar
    2.jar包版本问题
    解决办法:因为项目环境需要用jdk1.6,按照上述所示版本下载即可

    附jar包下载地址

    https://mvnrepository.com/artifact/org.apache.poi/ooxml-schemas/1.1

    展开全文
  • 利用下角标的方式处理word文档区域文字分割无法匹配的问题
  • poi_word_utils 使用poi绘制word图表以及表格的工具类项目 这里包含了投影普通柱状图堆叠柱状图簇状柱状图折线图饼状图散点图 其中柱状图和散点图加入了自定义颜色的功能在WordUtil类中main方法里面,基本上包含了...
  • POI 替换word2007文本框的值POI,包含word表中的文本框的值,定义好word模板即可替换word中的值。
  • 使用poi替换word中的文字和图片实现打印,注意代码中的jar包、图片、word位置
  • 使用java poi 替换word模板里面的内容

    千次阅读 2019-11-29 14:04:03
    使用java poi 替换word模板里面的内容需求背景功能实现对模板进一步加工,方便我们程序处理java代码验证 需求背景 业务提供了一个word的签名模板,要求根据订单内容替换模板中的关键信息,需要替换的内容已明确。 ...
  • Apache poi 根据word模板生成word报表 替换 循环列表 图片,代码调试过了,修改相应的图片位置,word模板路径即可运行
  • 2.替换文本的占位符为 ${xxx} ,在word中填写的时候,需要一次性输入,最好是在text编辑器中写好,然后复制过去。否则可能会被识别为 ${,xxx,} ,就无法替换了。 package org.jeecg.modules.utils; import ...
  • java poi 替换word内容

    万次阅读 2018-08-15 15:15:46
    以上数据为替换部分的数据。...以上为模版内容     /**  *   * @param params //需要替换的文字。  * @param wgylist1 //生成表格的list  * @param lzlist1 //生成表格的list  * @param dateStr   ...
  • 1. 普通的段落文字换行 ... * 段落/n替换成换行符 * * @param value * @param paragraph * @param run */ public static void setWrap(Object value, XWPFParagraph paragraph, XWPFRun run) { ...
  • poi 操作word文档 0. 参考文档 感谢大萌音音’s B站视频的分享, 如有不懂, 可以去看这个视频 1. poi 依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</...
  • java使用poi操作.doc word模板替换,循环插入表格
  • 项目中需要实现一个功能,动态替换给定模板里面的内容,生成word文档提供下载功能。中间解决了问题有:1.页眉的文档logo图片解决,刚开始的时候,HWPFDocument 对象无法读取图片对象(已测试)2.文档的水印也无法读取3...
  • 需求分析:工作中遇到的一个技术需求,需要用java代码操作Word,查找Word中的mark标记,然后进行替换,简而言之就是“替换word中的指定字符串”;解决办法:可以用JACOB和POI来实现,下面我用的是POI操作。用poi必须...
  • 最近在做一个根据模板导出word文件的功能,大体思路是在模板内使用变量占位,然后通过程序找到占位的变量,然后替换并导出。 经过一顿操作后发现一个问题,发现模板内有的变量可以被替换,有的不可以,模板如下 : ...
  • } } // 替换word中需要替换的特殊字符 public static boolean replaceAndGenerateWord(String srcPath, String destPath, Map map) { String[] sp = srcPath.split("\\."); String[] dp = destPath.split("\\."); ...
  • poi操作word替换内容以及生成pdf
  • 首先你要保证你写的标识符没有问题且名称也一模一样 解决办法:word模板写标识符的方法不对,你可以把先在记事本写好标识符如(${name}),将这个复制到word模板中,不要直接在模板中写,具体原理不太清楚 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,749
精华内容 1,499
关键字:

poi替换word内容