Java导出富文本到word

源码地址:

github:https://github.com/wesley5201314/java-export-word-plugin

gitosc:https://git.oschina.net/zhengweishan/export_word_plugin

背景

最近用java开发一个中车项目管理系统,里面有一个维修单word导出功能。

可用方案

在网上查找资料,总结出两种比较可行的方案。

(1) 制作word模板,导出成mht文件(单页面网页格式),然后往模板里渲染数据,最终生成word文档。

(2) 制作word模板,导出成xml文件,然后往模板里渲染数据,最终生成word文档。

两种都是采用模板的思想,比用poi去组织word格式简单的很多很多。不同点在于导出文件的格式不同,一个是mht文件,一个是xml文件。考虑到本项目中的维修单个别字段采用了富文本编辑器实现,保存进数据库中是html格式的字符串,所以采用第一种方案,即通过mht文件来实现。

实现思路

由于我们是要用word来解析带图片的富文本(说白了就是解析一段html,当然这段html代码是包含img标签:图片),so...传统的word模板导出(word另存为xml,在修改后缀为ftl)是行不通的,因为他解析不了html代码(至少我目前没有找到这方便的解决方案,大神勿喷~),这样的话我就要换用一种模板来处理这个模板:word模板另存为mht格式,再修改后缀为ftl。剩下的就是后台操作了,找到你存富文本的字段(html代码)获取里面的img标签,找到图片,并把图片解析为base64字符串,填充到我们只做的模板上就ok了。

实现步骤及注意事项

创建mht模板

根据模板引擎的语法规则填入占位符制作word模板,保存为mht文件。eg:

然后打开mht文件,在mht文件中插入图片资源的base64及xml 的href引用的占位。如下图:

${imagesBase64String} 和 ${imagesXmlHrefString}这两个是我们手动加进去的,这也是解析富文本的关键所在。

由于mht文件是采用的是“us-ascii”编码,属性后面都必须带有3D前缀。所以包含html内容的需进行一下替换操作。

全文检索gb2312把他改成utf-8,同时需要加上3D前缀,对应着格式来改 一般就这两种:

<meta http-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8">

Content-Type: text/html; charset=3D"utf-8"

处理数据

一般的属性数据组织起来简单,无非就是从数据库中获取,处理也简单。现在模拟一个富文本的数据

	//用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='w:\\2.jpg' />");
    sb.append("</br><span>wesley 演示 导出富文本!@@#######¥¥%%%%………………&&&**~~~~~~&&&&&&&&、、、、、、、、</span>");
    sb.append("</br><span>----多图分割线---</span>");
    sb.append("</br><img style='height:100px;width:200px;display:block;' src='w:\\1.jpg' />");
    sb.append("</br><span>中国梦,幸福梦!</span>");
    sb.append("</div>");

    RichObject richObject = new RichObject();
    richObject.setHtml(sb.toString());
    //--------------------此处可以spring配置文件配置,也可以直接读取属性文件获取------------------
    //从mht文件中找
    richObject.setDocSrcLocationPrex("file:///C:/268D4AA4"); //这里是从mht中获取的资源文件所在的文件夹
    richObject.setDocSrcParent("word.files"); //资源文件夹名字
    richObject.setNextPartId("01D2C8DD.BC13AF60"); //下一部分的ID
	//以下三个属性字段我也不是很懂 查询网上是这么用的 不过根据字段应该大致能猜到是做什么用的。
    richObject.setShapeidPrex("_x56fe__x7247__x0020");
    richObject.setTypeid("#_x0000_t75");
    richObject.setSpidPrex("_x0000_i");

    richObject.setWebAppliction(false);

	//这里封装了一个Hnadler处理对象,来处理数据。
	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("name", "wesley");
    data.put("datetime","2017-05-10");
    data.put("title","演示demo");
    data.put("context1", richHtmlHandler.getHandledDocBodyBlock());
    data.put("context2", richHtmlHandler.getHandledDocBodyBlock());
    data.put("context3", richHtmlHandler.getHandledDocBodyBlock());
    data.put("context4", richHtmlHandler.getHandledDocBodyBlock());
    data.put("context5", richHtmlHandler.getHandledDocBodyBlock());
    data.put("context6", richHtmlHandler.getHandledDocBodyBlock());

渲染模板

	String docFilePath = "w:\\temp_by_wesley.doc";//目标文件
    String templatePath = Class.class.getResource("/ftl").getPath();
    templatePath = java.net.URLDecoder.decode(templatePath,"utf-8");//这里我的路径有空格添加此处理
    logger.debug("------templatePath-------"+templatePath);
    WordGeneratorWithFreemarker.createDoc(templatePath,"word.ftl",data,docFilePath);


	/**
     * 创建doc文件
     * [@param](https://my.oschina.net/u/2303379) templatePath 模板所在路径 xxx/xxx/template
     * [@param](https://my.oschina.net/u/2303379) templateName 模板名字 xxx.ftl
     * [@param](https://my.oschina.net/u/2303379) dataMap 数据集合
     * [@param](https://my.oschina.net/u/2303379) 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,outPath);
    }

	 /**
     * 基于文件的输出
     *
     * @param templatePath 模板所在路径 xxx/xxx/template
     * @param templateName 模板名字 xxx.ftl
     * @param dataMap      数据集合
     * @param outPath      输出文件路径  xxx/xxx/xxx.doc
     */
    public static void fprint(String templatePath, String templateName, Map<String, Object> root, String outPath) {
        logger.debug("Freemarker fprint file");
        try {
            getInstance(templatePath);
            Template template = getTemplate(templateName);
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(outPath)), "UTF-8"));
            template.process(root, out);
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } catch (TemplateException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

效果展示

到此富文本导出就完成了。

转载于:https://my.oschina.net/zhengweishan/blog/1475577

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Apache POI库来实现Java文本导出Word。具体步骤如下: 1. 添加Apache POI库依赖,可以在Maven或Gradle中添加如下依赖: ```xml <!-- Apache POI --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> ``` 2. 创建一个新的Word文档: ```java XWPFDocument document = new XWPFDocument(); ``` 3. 添加段落和文本: ```java XWPFParagraph paragraph = document.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText("Hello, World!"); ``` 4. 添加文本样式,例如字体、颜色、加粗等: ```java run.setBold(true); run.setColor("FF0000"); run.setFontSize(20); ``` 5. 导出Word文档: ```java FileOutputStream out = new FileOutputStream("output.docx"); document.write(out); out.close(); document.close(); ``` 完整的示例代码如下: ```java import java.io.FileOutputStream; import java.io.IOException; import org.apache.poi.xwpf.usermodel.*; public class RichTextToWord { public static void main(String[] args) throws IOException { XWPFDocument document = new XWPFDocument(); XWPFParagraph paragraph = document.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText("Hello, World!"); run.setBold(true); run.setColor("FF0000"); run.setFontSize(20); FileOutputStream out = new FileOutputStream("output.docx"); document.write(out); out.close(); document.close(); } } ``` 运行该程序将会在当前目录下生成一个名为`output.docx`的Word文档,其中包含了一个加粗、红色、20号字体的Hello, World!文本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值