Java操作word文档大全(持续更新)

525 阅读2分钟

@[TOC]

一、根据模板导出word

1、需要的包

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.32</version>
</dependency>

2、准备word文档

1.用Microsoft Office Word打开word原件;

2.把需要动态修改的内容替换成${XX}的形式,如果有图片,尽量选择较小的图片几十K左右的小图片,并调整好位置,占位(小图片转换的base64数据少,便于修改);如下图 在这里插入图片描述

3.另存为,选择保存类型Word 2003 XML 文档(*.xml)【这里说一下为什么用Microsoft Office Word打开且要保存为Word 2003XML,本人亲测,用WPS找不到Word 2003XML选项,如果保存为Word XML,会有兼容问题,避免出现导出的word文档不能用Word 2003打开的问题】,保存的文件名不要是中文

4.用notepad++打开文件;

5.将文档内容中需要动态修改内容的地方,换成freemarker的标识。其实就是Map<String, Object>中key,如${landName}

6.在加入了图片占位的地方,会看到一片base64编码后的代码,把base64替换成${image},也就是Map<String, Object>中key,值必须要处理成base64;

  代码如:<w:binData w:name="wordml://自定义.png" xml:space="preserve">${xx}</w:binData>

  注意:“>${xx}<”这尖括号中间不能加任何其他的诸如空格,tab,换行等符号。

  如果需要循环,则使用:<#list maps as map></#list> maps是Map<String, Object>中key,值为数组,map为自定义;

在这里插入图片描述

7.标识替换完之后,模板就弄完了,另存为.ftl后缀文件即可。注意:一定不要用word打开ftl模板文件,否则xml内容会发生变化,导致前面的工作白做了。把最开始得到的doc模板文件和ftl文件放在同一级目录下

3、编码

import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.codec.binary.Base64;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WordUtil {

    public static void main(String[] args) {
        try {
            // 创建FreeMarker配置,参数是包版本号
            Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);
            cfg.setClassForTemplateLoading(WordUtil.class, "/"); // 会找到项目路径下
            cfg.setDefaultEncoding("UTF-8");

            // 加载模板文件
            Template template = cfg.getTemplate("template/test.ftl");

            Map<String, Object> data = new HashMap<>();
            data.put("name", "张三");
            data.put("age", "18");
            data.put("weather", "晴朗");
            // 图片需要转为base64
            data.put("img", getImgStr("E:\\netty.png"));
            data.put("major", "打电玩");

            List<Map<String, String>> list = new ArrayList<>();
            Map<String, String> m1 = new HashMap<>();
            m1.put("like", "篮球");
            list.add(m1);
            Map<String, String> m2 = new HashMap<>();
            m2.put("like", "足球");
            list.add(m2);
            data.put("list", list);

            // 生成Word文件
            // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开 
            // utf-8是一定要加的!
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:\\output.doc"), "utf-8"));
            template.process(data, out);

            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 将图片转换成Base64编码
     *
     * @param imgFile
     *            待处理图片
     * @return
     */
    public static String getImgStr(String imgFile) {
        // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理

        InputStream in = null;
        byte[] data = null;
        // 读取图片字节数组
        try {
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new String(Base64.encodeBase64(data));
    }
}

4、坑

注意,要按照顺序生成ftl文件!否则会有兼容性问题! https://blog.csdn.net/qq_35222232/article/details/100337967

生成的文件扩展名为doc!不是docx!如果扩展名改为docx的话,office打不开,但是wps能打开!

【重磅推荐!免费简单内网穿透神器!支持linux+windows】

推荐内网穿透神器【cpolar】www.cpolar.com/ 点击【免费注册】之后,输入自己的个人信息就可以注册一个账号啦! 本地web项目如何使用外网访问?教你轻松使用cpolar在windows搭建内网穿透 linux虚拟机部署的web项目如何使用外网访问?教你轻松使用cpolar在centos搭建内网穿透 linux虚拟机部署的MySQL如何使用外网访问?教你轻松使用cpolar在centos搭建内网穿透