美文网首页
DOC4J插入表格与HTML

DOC4J插入表格与HTML

作者: 千叶鸟 | 来源:发表于2019-06-13 17:52 被阅读0次

    请先阅读以下资料
    https://www.baeldung.com/docx4j
    官网
    官方论坛(挺有用的,大部分问题在这里都能检索到)

    开始

    添加maven依赖

    <!-- https://mvnrepository.com/artifact/org.docx4j/docx4j -->
    <dependency>
        <groupId>org.docx4j</groupId>
        <artifactId>docx4j</artifactId>
        <version>6.0.1</version>
    </dependency>
    

    我这边引入的是6.0.1版本的docx4j,而且并没有额外引入jaxb-api,目前没有发现有什么影响

    插入HTML

    一些基础的操作在baeldung的资料中已经有了,我就不再提及了,这里主要说明下如何将html文本插入到word中。

    在段落中插入Html

    public void insertHtml() {
            //  构建一个html内容
            String content = "<p style=\"color:red\">一段HTML</p>";
            String htmlStr = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html\"; charset=\"utf-8\"></head><body>" + content + "<p><br/></p></body></html>";
            
            WordprocessingMLPackage aPackage;
            try {
                //  创建一个临时文件
                File tempFile = File.createTempFile("test", ".docx");
                aPackage = WordprocessingMLPackage.createPackage();
                //  插入段落文本
                aPackage.getMainDocumentPart().addParagraphOfText("hello");
                //  插入HTML
                aPackage.getMainDocumentPart().addAltChunk(AltChunkType.Html, htmlStr.getBytes(Charsets.UTF_8));
                //  将构建的word内容保存到临时文件
                aPackage.save(tempFile);
            } catch (IOException | Docx4JException e) {
                e.printStackTrace();
            }
        }
    

    结果:


    image

    在表格中插入Html

    public void insertHtmlToTableCell() {
            //  构建一个html内容
            String content = "<p style=\"color:red\">一段HTML</p>";
    
            WordprocessingMLPackage aPackage;
            try {
                //  创建一个临时文件
                File tempFile = File.createTempFile("test", ".docx");
                aPackage = WordprocessingMLPackage.createPackage();
                MainDocumentPart mainDocumentPart = aPackage.getMainDocumentPart();
                mainDocumentPart.addStyledParagraphOfText("Title", "将HTML插入表格中");
    
                int rowsNum = 2;    //  生成表格的行数
                int columnNumber = 2;   //  生成表格的列数
                int writableWidthTwips = aPackage.getDocumentModel().getSections().get(0).getPageDimensions().getWritableWidthTwips();  //  文档的可写宽度
    
                //  创建表格对象
                Tbl tbl = TblFactory.createTable(rowsNum, columnNumber, writableWidthTwips / columnNumber);
                //  获取所有行对象
                List<Object> rows = tbl.getContent();
                setRowData(mainDocumentPart, rows, 0, "第一行", content);
                setRowData(mainDocumentPart, rows, 1, "第二行", content);
                //  将生成的表格插入到文档中
                mainDocumentPart.addObject(tbl);
                //  将构建的word内容保存到临时文件
                aPackage.save(tempFile);
            } catch (IOException | Docx4JException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 设置生成的教案word的行数据
         * @param mainDoc   MainDocumentPart对象
         * @param rows  创建的Tbl对象的所有行对象
         * @param rowIndex  操作的行的索引
         * @param label     第一列插入的内容
         * @param htmlContent   第二列插入的html内容(只需要核心html段就可以了)
         * @throws InvalidFormatException
         */
        private void setRowData(MainDocumentPart mainDoc, List<Object> rows, int rowIndex, String label, String htmlContent) throws InvalidFormatException {
            //  获取当前行
            Tr tr = (Tr) rows.get(rowIndex);
            //  获取所有列对象
            List<Object> cells = tr.getContent();
            Tc labelTc = (Tc) cells.get(0); //  label列
            Tc valueTc = (Tc) cells.get(1); //  content列
    
            //  设置label
            labelTc.getContent().add(createLabelP(label));
            //  设置content
            if (htmlContent != null) {
                /*
                  这里需要格外注意:
                  1. 必须额外加上<p><br/></p>,其中<br/>可为其它标签或非空内容,否则会导致生成的word有错误,无法打开
                  2. 需要设置html的字符集,否则html内容在部分word版本或跨平台word中会出现中文乱码的情况
                 */
                String contentStr = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html\"; charset=\"utf-8\"></head><body>" + htmlContent + "<p><br/></p></body></html>";
                //  创建并设置AlternativeFormatInputPart
                AlternativeFormatInputPart afiPart = new AlternativeFormatInputPart(new PartName("/hw" + rowIndex + ".html")); //CAUTION: each html part needs a new name!!
                afiPart.setBinaryData(contentStr.getBytes(Charsets.UTF_8));
                afiPart.setContentType(new ContentType("text/html"));
                //  创建CTAltChunk
                Relationship altChunkRel = mainDoc.addTargetPart(afiPart);
                CTAltChunk ac = Context.getWmlObjectFactory().createCTAltChunk();
                ac.setId(altChunkRel.getId());
                //  将ac写入第二列(前面的索引好像是指在哪个位置插入,具体自己查查吧~~~)
                valueTc.getContent().set(0, ac);
            }
        }
    
        /**
         * 创建普通的Label的样式配置
         * @param text  内容
         * @return  一个P节点
         */
        private P createLabelP(String text) {
            ObjectFactory factory = Context.getWmlObjectFactory();
            P p = factory.createP();
            R r = factory.createR();
            Text t = factory.createText();
            t.setValue(text);
            r.getContent().add(t);
            p.getContent().add(r);
            RPr rpr = factory.createRPr();
            BooleanDefaultTrue b = new BooleanDefaultTrue();
            rpr.setB(b);
            BooleanDefaultTrue caps = new BooleanDefaultTrue();
            rpr.setCaps(caps);
            Color green = factory.createColor();
            green.setVal("black");
            rpr.setColor(green);
    
            // 设置字体大小
            HpsMeasure size = new HpsMeasure();
            size.setVal(new BigInteger("18"));
            rpr.setSz(size);
            rpr.setSzCs(size);
            // 设置字体
            RFonts rFonts = rpr.getRFonts();
            if (rFonts==null) {
                rFonts = new RFonts();
                rpr.setRFonts(rFonts);
            }
            rFonts.setEastAsia("微软雅黑");
    
            r.setRPr(rpr);
            return p;
        }
    

    结果:


    image

    一些坑

    1. 在插入HTML的时候,一定要是完整的html内容(以<html>节点开口)
    2. 需要设置html的字符集,否则html内容在部分word版本或跨平台word中会出现中文乱码的情况
    3. 当在表格中插入HTML内容时,最后在</body>节点之前再添加个节点,如:<p><br/></p>,不然可能会遇到生成的word错误,无法打开的情况(我就遇到过:当<body>节点中的内容仅为一个<table>节点时)

    相关文章

      网友评论

          本文标题:DOC4J插入表格与HTML

          本文链接:https://www.haomeiwen.com/subject/kzqefctx.html