freemarker+docx4j 生产自定义word

  1. pom.xml 准备
    <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j-MOXy-JAXBContext</artifactId>
            <version>3.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>org.eclipse.persistence.moxy</artifactId>
            <version>2.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.23</version>
        </dependency>
        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j</artifactId>
            <version>3.2.1</version>
        </dependency>

2.准备一个word文档编辑好格式
word另存为xml
3,用notepad++ 打开xml 可以在notepad++上下载一个处理xml的插件(xml tools 的插件) 格式化xml
4,制作模板在模板中用${value} 替换你编辑好的word文档中需要替换的地方
比如

<w:r>
                            <w:rPr>
                                <w:rFonts w:ascii="仿宋_GB2312" w:fareast="仿宋_GB2312"
                                    w:h-ansi="宋体" w:hint="fareast" />
                                <wx:font wx:val="仿宋_GB2312" />
                                <w:b />
                                <w:b-cs />
                                <w:sz-cs w:val="21" />
                            </w:rPr>
                            <w:t>模板</w:t>
                        </w:r>

将模板这个汉子替换为

<w:r>
                            <w:rPr>
                                <w:rFonts w:ascii="仿宋_GB2312" w:fareast="仿宋_GB2312"
                                    w:h-ansi="宋体" w:hint="fareast" />
                                <wx:font wx:val="仿宋_GB2312" />
                                <w:b />
                                <w:b-cs />
                                <w:sz-cs w:val="21" />
                            </w:rPr>
                            <w:t>${templateName}</w:t>
                        </w:r>

如果遇到集合用<#list yourList as item> 这里放你要repeat的代码片段

public class WordGenerator {
    private final static Logger _logger = LoggerFactory.getLogger(WordGenerator.class);  
    private static Configuration configuration = null;

    public static Configuration getConfiguration() {
        configuration = new Configuration(Configuration.VERSION_2_3_23);
        try {
            configuration.setDirectoryForTemplateLoading(这里设置你项目中存放ftl文件的目录));
        } catch (IOException e) {
            _logger.error(e.getMessage(),e);
        }
        configuration.setDefaultEncoding("utf-8");
        configuration.setLogTemplateExceptions(false);
        return configuration;
    }
    /**
    *fileName 你要输出的文件名
    *dataMap ftl 需要显示的值
    *name ftl名称 ps: test.ftl
    **/
    public static File createDoc(String fileName,
            Map<?, ?> dataMap, String name) {
        configuration = getConfiguration();
        Writer w = null;
        File f = new File(fileName);
        FileOutputStream fos =null;
        try {
            Template t =configuration.getTemplate(name);
            fos =new FileOutputStream(f);
            w = new OutputStreamWriter(fos, "utf-8");
            t.process(dataMap, w);
            w.close();
        } catch (Exception ex) {
            //TODO
        } finally {
            IOUtils.closeQuietly(w);
            IOUtils.closeQuietly(fos);
        }
        return f;
    }
}

7,使用例子

/**ftl 中出现的${value} 这样的值 表现为dataMap中的key value则为你要显示的值**/
Map<String,Object> dataMap = new HashMap<>();
dataMap.put("tempdateName","测试");

File resumeFile = WordGenerator.createDoc(“test.xml”, dataMap, "resume.ftl");

//这样你就能得到你想要的xml
//这个xml可以用office word 打开,但是如果你想得到docx的文件,你可能会直接把xml重命名为xx.docx 但事实是 你这样做了之后,office word打不开提示错误那么接下来的操作比较重要
WordprocessingMLPackage wmlPackage = (WordprocessingMLPackage) WordprocessingMLPackage.load(new FileInputStream(resumeFile));
File file = new File("test.docx");
wmlPackage.save(file, Docx4J.FLAG_SAVE_ZIP_FILE);
这样 test.docx就可以正常用office word打开,而且在手机上也是可以正常打开的

笔者在执行上面的代码的时候发现非常慢 而且经常内存溢出。慢是应为docx4j初始化的时候比较慢,只是第一次执行比较慢,后面的都很快,google了很多还没找到比较靠谱的解决方法。
内存溢出 是docx4j初始化jaxb的时候比较吃PermGen space 的内存
解决方法:设置tomcat的启动参数,把tomcatjvm的 PermGen space设大一点,默认大小为:85m
这里写图片描述
这里写图片描述

设置为tomcat的jvm之后,运行稳定,而且比较快。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值