freemarker富文本生成word

1.添加依赖

<dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.28</version>
        </dependency>
        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j</artifactId>
            <version>6.1.2</version>
        </dependency>
        <!--  poi  -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>xdocreport</artifactId>
            <version>1.0.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>ooxml-schemas</artifactId>
            <version>1.3</version>
        </dependency>

2.新建word

添加内容

项目编号:${projectCode!}



${ title!}





表2 -列表
${list!}

另存为mht文件

修改为ftl

修改内容,去掉${}间的样式文字

如果有图片需要添加 ${imagesBase64String}和${imagesXmlHrefString}

添加工具类

public class RichHtmlHandler {
    private static final Logger logger = LoggerFactory.getLogger(RichHtmlHandler.class);
    private String handledDocBodyBlock; //富文本所在doc中的区域
    private List<String> docBase64BlockResults = new ArrayList<String>(); //文档中图片64位编码的结果区
    private List<String> xmlImgRefs = new ArrayList<String>(); //图片在xml中的短路径
    private RichObject richObject = null; //富文本对象
    private Document doc = null; //默认文档为空

    public RichHtmlHandler() {
        super();
    }

    public RichHtmlHandler(RichObject richObj) throws IOException {
        this.richObject = richObj;
        doc = Jsoup.parse(wrappHtml(richObject.getHtml()));
        handledHtml(richObject.getWebAppliction());
    }

    /**
     * 处理html
     *
     * @param isWebApplication
     * @throws IOException
     */
    public void handledHtml(boolean isWebApplication)
            throws IOException {
        logger.debug("RichHtmlHandler handledHtml isWebApplication:" + isWebApplication);
        Elements imags = doc.getElementsByTag("img");
        if (imags == null || imags.size() == 0) {
            // 返回编码后字符串
            return;
            //handledDocBodyBlock = WordHtmlGeneratorHelper.string2Ascii(html);
        }
        // 转换成word mht 能识别图片标签内容,去替换html中的图片标签
        for (Element item : imags) {
            // 把文件取出来
            String src = item.attr("src");
            String srcRealPath = src;
            if (isWebApplication) {
                String contentPath = RequestResponseContext.getRequest().getContextPath();
                if (!StringUtils.isEmpty(contentPath)) {
                    if (src.startsWith(contentPath)) {
                        src = src.substring(contentPath.length());
                    }
                }
                srcRealPath = RequestResponseContext.getRequest().getSession()
                        .getServletContext().getRealPath(src);
            }
            File imageFile = new File(srcRealPath);
            String imageFielShortName = imageFile.getName();
            String fileTypeName = FileUtils.getFileSuffix(srcRealPath);
            String docFileName = "image" + UUIDUtils.get32UUID() + "."
                    + fileTypeName;
            String srcLocationShortName = richObject.getDocSrcParent() + "/" + docFileName;
            String styleAttr = item.attr("style"); // 样式
            //高度
            String imagHeightStr = item.attr("height");
            ;
            if (StringUtils.isEmpty(imagHeightStr)) {
                imagHeightStr = getStyleAttrValue(styleAttr, "height");
            }
            //宽度
            String imagWidthStr = item.attr("width");
            ;
            if (StringUtils.isEmpty(imagHeightStr)) {
                imagHeightStr = getStyleAttrValue(styleAttr, "width");
            }
            imagHeightStr = imagHeightStr.replace("px", "");
            imagWidthStr = imagWidthStr.replace("px", "");
            if (StringUtils.isEmpty(imagHeightStr)) {
                //去得到默认的文件高度
                imagHeightStr = "0";
            }
            if (StringUtils.isEmpty(imagWidthStr)) {
                imagWidthStr = "0";
            }
            int imageHeight = Integer.parseInt(imagHeightStr);
            int imageWidth = Integer.parseInt(imagWidthStr);
            //得到文件的word mht的body块
            String handledDocBodyBlock = WordImageConvertor.toDocBodyBlock(srcRealPath,
                    imageFielShortName, imageHeight, imageWidth, styleAttr,
                    srcLocationShortName, richObject.getShapeidPrex(), richObject.getSpidPrex(), richObject.getTypeid());
            item.after(handledDocBodyBlock);
            //item.parent().append(handledDocBodyBlock);
            item.remove();
            // 去替换原生的html中的imag
            String base64Content = WordImageConvertor
                    .imageToBase64(srcRealPath);
            String contextLocation = richObject.getDocSrcLocationPrex() + "/" + richObject.getDocSrcParent()
                    + "/" + docFileName;
            String docBase64BlockResult = WordImageConvertor
                    .generateImageBase64Block(richObject.getNextPartId(), contextLocation,
                            fileTypeName, base64Content);
            docBase64BlockResults.add(docBase64BlockResult);
            String imgXMLHref = "<o:File HRef=3D\"" + docFileName + "\"/>";
            xmlImgRefs.add(imgXMLHref);
        }
    }

    /**
     * 获取样式的属性值
     *
     * @param style
     * @param attributeKey
     * @return
     */
    private String getStyleAttrValue(String style, String attributeKey) {
        if (StringUtils.isEmpty(style)) {
            return "";
        }
        // 以";"分割
        String[] styleAttrValues = style.split(";");
        for (String item : styleAttrValues) {
            // 在以 ":"分割
            String[] keyValuePairs = item.split(":");
            if (attributeKey.equals(keyValuePairs[0])) {
                return keyValuePairs[1];
            }
        }
        return "";
    }

    /**
     * 给html添加必须的标签
     *
     * @param html
     * @return
     */
    private String wrappHtml(String html) {
        // 因为传递过来都是不完整,需要添加以下标签
        StringBuilder sb = new StringBuilder();
        sb.append("<html>");
        sb.append("<body>");
        sb.append(html);
        sb.append("</body>");
        sb.append("</html>");
        return sb.toString();
    }

    public String getHandledDocBodyBlock() {
        String raw = WordHtmlGeneratorHelper.string2Ascii(doc.getElementsByTag("body").html());
        return raw.replace("=3D", "=").replace("=", "=3D");
        //return handledDocBodyBlock;
    }

    public void setHandledDocBodyBlock(String handledDocBodyBlock) {
        this.handledDocBodyBlock = handledDocBodyBlock;
    }

    public List<String> getDocBase64BlockResults() {
        return docBase64BlockResults;
    }

    public void setDocBase64BlockResults(List<String> docBase64BlockResults) {
        this.docBase64BlockResults = docBase64BlockResults;
    }

    public List<String> getXmlImgRefs() {
        return xmlImgRefs;
    }

    public void setXmlImgRefs(List<String> xmlImgRefs) {
        this.xmlImgRefs = xmlImgRefs;
    }

    public RichObject getRichObject() {
        return richObject;
    }

    public void setRichObject(RichObject richObject) {
        this.richObject = richObject;
    }
}

 

public class WordGeneratorWithFreemarker {
    private static final Logger logger = LoggerFactory.getLogger(WordGeneratorWithFreemarker.class);

    /**
     * 创建doc文件
     *
     * @param templatePath 模板所在路径 xxx/xxx/template
     * @param templateName 模板名字 xxx.ftl
     * @param dataMap      数据集合
     * @param outPath      输出文件路径  xxx/xxx/xxx.doc
     */
    public static void createDoc(String templatePath, String templateName, Map<String, Object> dataMap, String outPath) throws Exception {
        logger.debug("WordGeneratorWithFreemarker createDoc()");
        Freemarker.fprint(templatePath, templateName, dataMap, new FileOutputStream(new File(outPath)));
    }

    /**
     * 创建doc文件
     *
     * @param templatePath 模板所在路径 xxx/xxx/template
     * @param templateName 模板名字 xxx.ftl
     * @param dataMap      数据集合
     * @param response     文件流
     */
    public static void createDoc(String templatePath, String templateName, Map<String, Object> dataMap, HttpServletResponse response) throws Exception {
        logger.debug("WordGeneratorWithFreemarker createDoc()");
        String fileName = "招标方案";
        OutputStream out = response.getOutputStream();
        response.reset();
        response.addHeader("Content-Disposition", "attachment;filename=" + fileName + ".doc");
        Freemarker.fprint(templatePath, templateName, dataMap, response.getOutputStream());
        out.flush();
        out.close();
    }

    /**
     * 创建富文本Html处理器,主要处理图片及编码
     *
     * @param richObject 需要的参数
     * @return
     */
    public static RichHtmlHandler createRichHtmlHandler(RichObject richObject) throws Exception {
        logger.debug("WordGeneratorWithFreemarker createRichHtmlHandler()");
        RichHtmlHandler richHtmlHandler = new RichHtmlHandler(richObject);
        return richHtmlHandler;
    }

    /**
     * 获取图片的64位字符串
     *
     * @param richHtmlHandlerList
     * @return
     */
    public static String getImagesBase64String(List<RichHtmlHandler> richHtmlHandlerList) {
        logger.debug("WordGeneratorWithFreemarker getImagesBase64String()");
        String imagesBase64String = "";
        for (RichHtmlHandler richHtmlHandler : richHtmlHandlerList) {
            if (!CollectionUtils.isEmpty(richHtmlHandler.getDocBase64BlockResults())) {
                for (String item : richHtmlHandler.getDocBase64BlockResults()) {
                    imagesBase64String += item + "\n";
                }
            }
        }
        logger.debug("WordGeneratorWithFreemarker getImagesBase64String() result:" + imagesBase64String);
        return imagesBase64String;
    }

    /**
     * 获取图片在xml中的端路径
     *
     * @param richHtmlHandlerList
     * @return
     */
    public static String getXmlImgHref(List<RichHtmlHandler> richHtmlHandlerList) {
        logger.debug("WordGeneratorWithFreemarker getXmlImgHref()");
        String xmlImgHref = "";
        for (RichHtmlHandler richHtmlHandler : richHtmlHandlerList) {
            if (!CollectionUtils.isEmpty(richHtmlHandler.getXmlImgRefs())) {
                for (String item : richHtmlHandler.getXmlImgRefs()) {
                    xmlImgHref += item + "\n";
                }
            }
        }
        logger.debug("WordGeneratorWithFreemarker getXmlImgHref() result:" + xmlImgHref);
        return xmlImgHref;
    }
}
public class RichObject {
    private String html; //富文本html文件
    //指doc转成mht之后的一些基础配置
    private String docSrcParent = ""; //文档父类
    private String docSrcLocationPrex = ""; //文档本地前缀
    private String nextPartId; //下一个父类
    private String shapeidPrex; //文档中shapeid前缀
    private String spidPrex; //文档中spid的前缀
    private String typeid; //类型ID
    private Boolean isWebAppliction; //是不是web应用

    public String getHtml() {
        return html;
    }

    public void setHtml(String html) {
        this.html = html;
    }

    public String getDocSrcParent() {
        return docSrcParent;
    }

    public void setDocSrcParent(String docSrcParent) {
        this.docSrcParent = docSrcParent;
    }

    public String getDocSrcLocationPrex() {
        return docSrcLocationPrex;
    }

    public void setDocSrcLocationPrex(String docSrcLocationPrex) {
        this.docSrcLocationPrex = docSrcLocationPrex;
    }

    public String getNextPartId() {
        return nextPartId;
    }

    public void setNextPartId(String nextPartId) {
        this.nextPartId = nextPartId;
    }

    public String getShapeidPrex() {
        return shapeidPrex;
    }

    public void setShapeidPrex(String shapeidPrex) {
        this.shapeidPrex = shapeidPrex;
    }

    public String getSpidPrex() {
        return spidPrex;
    }

    public void setSpidPrex(String spidPrex) {
        this.spidPrex = spidPrex;
    }

    public String getTypeid() {
        return typeid;
    }

    public void setTypeid(String typeid) {
        this.typeid = typeid;
    }

    public Boolean getWebAppliction() {
        return isWebAppliction;
    }

    public void setWebAppliction(Boolean webAppliction) {
        isWebAppliction = webAppliction;
    }

    @Override
    public String toString() {
        return "RichObject{" +
                "html='" + html + '\'' +
                ", docSrcParent='" + docSrcParent + '\'' +
                ", docSrcLocationPrex='" + docSrcLocationPrex + '\'' +
                ", nextPartId='" + nextPartId + '\'' +
                ", shapeidPrex='" + shapeidPrex + '\'' +
                ", spidPrex='" + spidPrex + '\'' +
                ", typeid='" + typeid + '\'' +
                ", isWebAppliction=" + isWebAppliction +
                '}';
    }
}

编写测试类

public class ClientExample {
    private static final Logger logger = LoggerFactory.getLogger(ClientExample.class);

    public static void main(String[] agrs) throws Exception {
        //用map存放数据
        HashMap<String, Object> data = new HashMap<String, Object>();
        //创建富文本
        StringBuilder sb = new StringBuilder();
        sb.append("<div>");
        sb.append("<img style='height:100px;width:200px;display:block;' src='D:\\temp\\1.png' />");
        sb.append("</br><span>wesley 演示 导出富文本!@@#######¥¥%%%%………………&&&**~~~~~~&&&&&&&&、、、、、、、、</span>");
        sb.append("</br><span>----多图分割线---</span>");
        sb.append("</br><img style='height:100px;width:200px;display:block;' src='D:\\temp\\2.png' />");
        sb.append("</br><span>中国梦,幸福梦!</span>");
        sb.append("</div>");
        RichObject richObject = new RichObject();
        richObject.setHtml(sb.toString());
        //--------------------此处可以spring配置文件配置,也可以直接读取属性文件获取------------------
        //从mht文件中找
        richObject.setDocSrcLocationPrex("file:///C:/268BA2D4");
        richObject.setDocSrcParent("test.files");
        richObject.setNextPartId("01D5AADE.67ACB0D0");
        richObject.setShapeidPrex("_x56fe__x7247__x0020");
        richObject.setTypeid("#_x0000_t75");
        richObject.setSpidPrex("_x0000_i");
        richObject.setWebAppliction(false);
        //-----------------------------------------
        RichHtmlHandler richHtmlHandler = WordGeneratorWithFreemarker.createRichHtmlHandler(richObject);
        List<RichHtmlHandler> richHtmlHandlerList = new ArrayList<RichHtmlHandler>();
        richHtmlHandlerList.add(richHtmlHandler);
        data.put("imagesXmlHrefString", WordGeneratorWithFreemarker.getXmlImgHref(richHtmlHandlerList));
        logger.debug("------imagesXmlHrefString-------" + WordGeneratorWithFreemarker.getXmlImgHref(richHtmlHandlerList));
        data.put("imagesBase64String", WordGeneratorWithFreemarker.getImagesBase64String(richHtmlHandlerList));
        logger.debug("------imagesBase64String-------" + WordGeneratorWithFreemarker.getImagesBase64String(richHtmlHandlerList));
        data.put("projectCode", "1234");
        data.put("title", "演示demo");
        data.put("list", richHtmlHandler.getHandledDocBodyBlock());
        String docFilePath = "D:\\test.doc";
        String templatePath = Class.class.getResource("/ftl").getPath();
        templatePath = java.net.URLDecoder.decode(templatePath, "utf-8");//这里我的路径有空格添加此处理
        logger.debug("------templatePath-------" + templatePath);
        WordGeneratorWithFreemarker.createDoc(templatePath, "test.ftl", data, docFilePath);
    }
}

运行效果

springboot导出

@Override
    public void export(HttpServletRequest request, HttpServletResponse response, String tmplId, String prjId) throws Exception {
        //用map存放数据
        HashMap<String, Object> data = getData(prjId);
        //
        TemplateConfig templateConfig = templateConfigService.selectByPrimaryKey(tmplId);
        String templateName = templateConfig.getTemplateName();
//        getRichContent(templateConfig,"");
        String templatePath = Class.class.getResource("/ftl").getPath();
        templatePath = java.net.URLDecoder.decode(templatePath, "utf-8");
        logger.debug("------templatePath-------" + templatePath);
        WordGeneratorWithFreemarker.createDoc(templatePath, templateName + ".ftl", data, response);
    }

    private String getRichContent(TemplateConfig templateConfig, String content) throws Exception {
        RichObject richObject = getRichObject(templateConfig);
        richObject.setHtml(content);
        RichHtmlHandler richHtmlHandler = WordGeneratorWithFreemarker.createRichHtmlHandler(richObject);
        List<RichHtmlHandler> richHtmlHandlerList = new ArrayList<RichHtmlHandler>();
        richHtmlHandlerList.add(richHtmlHandler);
        return richHtmlHandler.getHandledDocBodyBlock();
    }

    private HashMap<String, Object> getData(String projectId) {
        Map map = planTenderMapper.getProjectInfo(projectId);
        HashMap<String, Object> data = new HashMap<String, Object>();
        data.put("projectCode", "200000000002168");
        data.put("dateYear", "2019");
        data.put("evaluationMethod", "xx");
        data.put("bidDivision", "xx");
        data.put("evaluationWeight", "xx");
        data.put("suppliersNumber", "xx");
        data.put("winningNumber", "xx");
        data.put("biddingAgency", "xx");
        data.put("serviceUnit", "xx");
        data.put("completionTime", "2019年12月");
        return data;
    }

    private RichObject getRichObject(TemplateConfig templateConfig) {
        RichObject richObject = new RichObject();
        //--------------------此处可以spring配置文件配置,也可以直接读取属性文件获取------------------
        //从mht文件中找
        richObject.setDocSrcLocationPrex("file:///C:/" + templateConfig.getLocationPrex());
        richObject.setDocSrcParent(templateConfig.getTemplateName() + ".files");
        richObject.setNextPartId(templateConfig.getNextPartId());
        richObject.setShapeidPrex("_x56fe__x7247__x0020");
        richObject.setTypeid("#_x0000_t75");
        richObject.setSpidPrex("_x0000_i");
        richObject.setWebAppliction(false);
        //-----------------------------------------
        return richObject;
    }

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值