poi对word的操作

    excle因为是单元格为单位,所以操作十分简便,相对于它来说,word操作相对复杂一些,word操作主要用来做文本内容的替换来实现动态生成word,下面把我对这一块的思想,以及操作进行一下总结。

    0.和excle一样有一个老版本的文件格式为doc格式,对应对象名称为HWPFDocument,最新的docx格式对应的对象为XWPFDocument,这里以后者为例。因为在工作中处理表格,一般抬头为一行描述,如标题年月日名称等,然后下面是表格内容填充这种形式,所以以下操作就以这种文件内容作为处理对象举例。

    1.XWPFDocument docx = new XWPFDocument(inputstream);// word主要就通过传入文件流的方式进行实例化。

    2.List<XWPFParagraph> allXWPFParagraphs = docx.getParagraphs(); 拿到文本段落 一行数据为一个XWPFParagraph对象。

        遍历上面的allXWPFParagraphs -> for (XWPFParagraph xwpfParagraph : paragraphs)

       通过List<XWPFRun> run = xwpfParagraph.getRuns();拿到段落中的文本 以符号或者不同数据类型终结,就像是一句话会以句号结束。

        遍历上面 话语集合 -> for (int i = 0; i < run.size(); i++)

        run.get(i).setText(要设置的值, 从哪个位置开始)   ,替换掉某句话

      3. 因为在网上找了很多例子不太好用,所以在工作中自行写了一个文本转换的工具类,以方便使用。代码如下:

       /**
     * 导出word(新)
     * @author 牛牧原
     * @param tempMap 名字替换
     * @param tempFilePath 读取文件路径
     * @param response 响应
     * @param fileName 下载文件名
     * @throws Exception
     */
    public void docxFileExport(Map<String, String> tempMap, String tempFilePath,
            HttpServletResponse response, String fileName) throws Exception {
        XWPFDocument docx = new XWPFDocument(new FileInputStream(tempFilePath));    
        List<XWPFParagraph> paragraphs = docx.getParagraphs();
        
        for (XWPFParagraph xwpfParagraph : paragraphs) {
            List<XWPFRun> run = xwpfParagraph.getRuns();
            for (int i = 0; i < run.size(); i++) {
                for (Map.Entry<String, String> entry : tempMap.entrySet()) {
                    String val = run.get(i).getText(run.get(i).getTextPosition());
                    if (val != null && val.equals(entry.getKey())) {
                        run.get(i).setText(entry.getValue(), 0);
                    }
                }
            }
        }
        
        // 美滋滋循环
        List<XWPFTable> tables = docx.getTables();
        for (XWPFTable table : tables) {
            List<XWPFTableRow> rows = table.getRows();
            for (XWPFTableRow row : rows) {
                List<XWPFTableCell> cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    List<XWPFParagraph> cellPara = cell.getParagraphs();
                    for (XWPFParagraph xwpfParagraph : cellPara) {
                        List<XWPFRun> run = xwpfParagraph.getRuns();
                        for (int i = 0; i < run.size(); i++) {
                            for (Map.Entry<String, String> entry : tempMap.entrySet()) {
                                String val = run.get(i).getText(run.get(i).getTextPosition());
                                if (val != null && val.equals(entry.getKey())) {
                                    run.get(i).setText(entry.getValue(), 0);
                                }
                            }
                        }
                    }
                }
            }
        }
        ByteArrayOutputStream os = new ByteArrayOutputStream();                
        docx.write(os);
        byte[] content = os.toByteArray();
        InputStream is = new ByteArrayInputStream(content);
        response.reset();
        response.setContentType("application/x-download;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename="
            + new String((fileName+ System.currentTimeMillis() + ".docx").getBytes(), "iso-8859-1"));
        response.setHeader("Set-Cookie", "fileDownload=true; path=/");
        ServletOutputStream out = response.getOutputStream();
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
          bis = new BufferedInputStream(is);
          bos = new BufferedOutputStream(out);
          byte[] buff = new byte[2048];
          int bytesRead;
          while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
            bos.write(buff, 0, bytesRead);
          }
        } catch (Exception e) {
          e.printStackTrace();
        } finally {
          if (bis != null)
            bis.close();
          if (bos != null)
            bos.close();
        }
    }

  4.该代码简单讲解,以便日后复用

扫描二维码关注公众号,回复: 76103 查看本文章

     需要自己先设定好word模板,然后将需要添字部分设置为任意的英文组合例如 nmy。然后设置要替换的map,key为要替换的关键字,value为要替换成的内容,该方法最后会弹出下载,        response.setHeader("Set-Cookie", "fileDownload=true; path=/");防止多次点击下载,通过内存流最后弹出下载。为了防止乱码设置new String((fileName+ System.currentTimeMillis() + ".docx").getBytes(), "iso-8859-1")) 然后好像也没啥了吧。。。

     

猜你喜欢

转载自my.oschina.net/huaizhe/blog/1624460