zoukankan      html  css  js  c++  java
  • java使用POI操作XWPFDocument 生成Word实战(一)

    注:我使用的word 2016
    功能简介:
    (1)使用jsoup解析html得到我用来生成word的文本(这个你们可以忽略)
    (2)生成word、设置页边距、设置页脚(页码),设置页码(文本)

    一、解析html

    Document doc = Jsoup.parseBodyFragment(contents);
    Element body = doc.body();
    Elements es = body.getAllElements();

    二、循环Elements获取我需要的html标签

    boolean tag = false;
    for (Element e : es) {
        //跳过第一个(默认会把整个对象当做第一个)
        if(!tag) {
            tag = true;
            continue;
        }
        //创建段落:生成word(核心)
        createXWPFParagraph(docxDocument,e);
    }

    三、生成段落

    /**
     * 构建段落
     * @param docxDocument
     * @param e
     */
    public static void createXWPFParagraph(XWPFDocument docxDocument, Element e){
        XWPFParagraph paragraph = docxDocument.createParagraph();
        XWPFRun run = paragraph.createRun();
        run.setText(e.text());
        run.setTextPosition(35);//设置行间距
        
        if(e.tagName().equals("titlename")){
            paragraph.setAlignment(ParagraphAlignment.CENTER);//对齐方式
    
            run.setBold(true);//加粗
            run.setColor("000000");//设置颜色--十六进制
            run.setFontFamily("宋体");//字体
            run.setFontSize(24);//字体大小
            
        }else if(e.tagName().equals("h1")){
            addCustomHeadingStyle(docxDocument, "标题 1", 1);
            paragraph.setStyle("标题 1");
            
            run.setBold(true);
            run.setColor("000000");
            run.setFontFamily("宋体");
            run.setFontSize(20);
        }else if(e.tagName().equals("h2")){
            addCustomHeadingStyle(docxDocument, "标题 2", 2);
            paragraph.setStyle("标题 2");
            
            run.setBold(true);
            run.setColor("000000");
            run.setFontFamily("宋体");
            run.setFontSize(18);
        }else if(e.tagName().equals("h3")){
            addCustomHeadingStyle(docxDocument, "标题 3", 3);
            paragraph.setStyle("标题 3");
            
            run.setBold(true);
            run.setColor("000000");
            run.setFontFamily("宋体");
            run.setFontSize(16);
        }else if(e.tagName().equals("p")){
            //内容
            paragraph.setAlignment(ParagraphAlignment.BOTH);//对齐方式
            paragraph.setIndentationFirstLine(WordUtil.ONE_UNIT);//首行缩进:567==1厘米
            
            run.setBold(false);
            run.setColor("001A35");
            run.setFontFamily("宋体");
            run.setFontSize(14);
            //run.addCarriageReturn();//回车键
        }else if(e.tagName().equals("break")){
            paragraph.setPageBreak(true);//段前分页(ctrl+enter)
        }
    }    

    四、设置页边距

    /**
    * 设置页边距 (word中1厘米约等于567) 
    * @param document
    * @param left
    * @param top
    * @param right
    * @param bottom
    */
    public static void setDocumentMargin(XWPFDocument document, String left,String top, String right, String bottom) {  
    CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
    CTPageMar ctpagemar = sectPr.addNewPgMar();
    if (StringUtils.isNotBlank(left)) {  
      ctpagemar.setLeft(new BigInteger(left));  
    }  
    if (StringUtils.isNotBlank(top)) {  
      ctpagemar.setTop(new BigInteger(top));  
    }  
    if (StringUtils.isNotBlank(right)) {  
      ctpagemar.setRight(new BigInteger(right));  
    }  
    if (StringUtils.isNotBlank(bottom)) {  
      ctpagemar.setBottom(new BigInteger(bottom));  
    }  
    } 

    五、创建页眉

    /**
     * 创建默认页眉
     *
     * @param docx XWPFDocument文档对象
     * @param text 页眉文本
     * @return 返回文档帮助类对象,可用于方法链调用
     * @throws XmlException XML异常
     * @throws IOException IO异常
     * @throws InvalidFormatException 非法格式异常
     * @throws FileNotFoundException 找不到文件异常
     */
    public static void createDefaultHeader(final XWPFDocument docx, final String text){
        CTP ctp = CTP.Factory.newInstance();
        XWPFParagraph paragraph = new XWPFParagraph(ctp, docx);
        ctp.addNewR().addNewT().setStringValue(text);
        ctp.addNewR().addNewT().setSpace(SpaceAttribute.Space.PRESERVE);
        CTSectPr sectPr = docx.getDocument().getBody().isSetSectPr() ? docx.getDocument().getBody().getSectPr() : docx.getDocument().getBody().addNewSectPr();
        XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(docx, sectPr);
        XWPFHeader header = policy.createHeader(STHdrFtr.DEFAULT, new XWPFParagraph[] { paragraph });
        header.setXWPFDocument(docx);
    }}

    六、创建页脚

    /**
     * 创建默认的页脚(该页脚主要只居中显示页码)
     * 
     * @param docx
     *            XWPFDocument文档对象
     * @return 返回文档帮助类对象,可用于方法链调用
     * @throws XmlException
     *             XML异常
     * @throws IOException
     *             IO异常
     */
    public static void createDefaultFooter(final XWPFDocument docx) {
        // TODO 设置页码起始值
        CTP pageNo = CTP.Factory.newInstance();
        XWPFParagraph footer = new XWPFParagraph(pageNo, docx);
        CTPPr begin = pageNo.addNewPPr();
        begin.addNewPStyle().setVal(STYLE_FOOTER);
        begin.addNewJc().setVal(STJc.CENTER);
        pageNo.addNewR().addNewFldChar().setFldCharType(STFldCharType.BEGIN);
        pageNo.addNewR().addNewInstrText().setStringValue("PAGE   \* MERGEFORMAT");
        pageNo.addNewR().addNewFldChar().setFldCharType(STFldCharType.SEPARATE);
        CTR end = pageNo.addNewR();
        CTRPr endRPr = end.addNewRPr();
        endRPr.addNewNoProof();
        endRPr.addNewLang().setVal(LANG_ZH_CN);
        end.addNewFldChar().setFldCharType(STFldCharType.END);
        CTSectPr sectPr = docx.getDocument().getBody().isSetSectPr() ? docx.getDocument().getBody().getSectPr() : docx.getDocument().getBody().addNewSectPr();
        XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(docx, sectPr);
        policy.createFooter(STHdrFtr.DEFAULT, new XWPFParagraph[] { footer });
    }

    七、自定义标题样式(这个在我另一篇word基础中也有提及)

    /**
     * 增加自定义标题样式。这里用的是stackoverflow的源码
     * 
     * @param docxDocument 目标文档
     * @param strStyleId 样式名称
     * @param headingLevel 样式级别
     */
    private static void addCustomHeadingStyle(XWPFDocument docxDocument, String strStyleId, int headingLevel) {
    
        CTStyle ctStyle = CTStyle.Factory.newInstance();
        ctStyle.setStyleId(strStyleId);
    
        CTString styleName = CTString.Factory.newInstance();
        styleName.setVal(strStyleId);
        ctStyle.setName(styleName);
    
        CTDecimalNumber indentNumber = CTDecimalNumber.Factory.newInstance();
        indentNumber.setVal(BigInteger.valueOf(headingLevel));
    
        // lower number > style is more prominent in the formats bar
        ctStyle.setUiPriority(indentNumber);
    
        CTOnOff onoffnull = CTOnOff.Factory.newInstance();
        ctStyle.setUnhideWhenUsed(onoffnull);
    
        // style shows up in the formats bar
        ctStyle.setQFormat(onoffnull);
    
        // style defines a heading of the given level
        CTPPr ppr = CTPPr.Factory.newInstance();
        ppr.setOutlineLvl(indentNumber);
        ctStyle.setPPr(ppr);
    
        XWPFStyle style = new XWPFStyle(ctStyle);
    
        // is a null op if already defined
        XWPFStyles styles = docxDocument.createStyles();
    
        style.setType(STStyleType.PARAGRAPH);
        styles.addStyle(style);
    
    }

    八、设置页码大小及纸张方向

    /** 
     * 设置页面大小及纸张方向 landscape横向
     * @param document
     * @param width
     * @param height
     * @param stValue
     */
    public void setDocumentSize(XWPFDocument document, String width,String height, STPageOrientation.Enum stValue) {
        CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
        CTPageSz pgsz = sectPr.isSetPgSz() ? sectPr.getPgSz() : sectPr.addNewPgSz();
        pgsz.setH(new BigInteger(height));
        pgsz.setW(new BigInteger(width));
        pgsz.setOrient(stValue);
    }

    九、效果展示

     

    十、demo源码及生成的word文件(相应的jar包大家可以去阿里的maven仓库下载)

     demo:https://pan.baidu.com/s/1jHFLniI

  • 相关阅读:
    【C#食谱】【风味小吃】菜单2:角度转换为弧度
    16 Rules for Managers
    word打不开,要在安全模式下才能打开
    禁止修改IP地址工具及原理
    VB编程读取本地计算机IP地址及MAC地址
    联想TinkCenter 8000T 安装XP需要修改CMOS
    使用nLite封装2003集成Raid卡驱动
    怎么样让台式机通过笔记本无线上网 台式机共享上网 笔记本当无线路由器 两台电脑一根网线
    VB使用ADODB操作数据库的常用方法
    转:[震惊] 这两天发现被穿的真正原因——QQ电脑管家
  • 原文地址:https://www.cnblogs.com/unruly/p/7552998.html
Copyright © 2011-2022 走看看