欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用freemarker生成word模板

程序员文章站 2022-04-30 09:26:16
...

需求:
给文书统一生成一个搞头文件,文件内容基本是一样的。
用freemarker生成docx文档
一、生成一个docx结尾的word模板,然后把文档的后缀docx改成zip,zip里会有生成很多文件。如下图:
用freemarker生成word模板
然后打开word文件夹,如下图:
用freemarker生成word模板
把document.xml拿出来,把后缀xml改成ftl,然后把里面的内容(在线格式化xml)格式化一下,把一些可变的参数做成变量。
二、在resources文件夹下创建wordTemplates文件夹,里面放刚才的zip和改名的gtwj.ftl文件。
三、替换word模板类:

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class ZipUtils {

    private static final Logger logger = LoggerFactory.getLogger(ZipUtils.class);
    /**
     * 替换document , header1
     *
     * @param zipInputStream  zip文件的zip输入流
     * @param zipOutputStream 输出的zip输出流
     * @param bodyOs        要替换的 word内容流
     */
    public static void replaceItem(ZipInputStream zipInputStream, ZipOutputStream zipOutputStream,
                                   ByteArrayOutputStream bodyOs) {

        String bodyname = "word/document.xml";
        //
        if (null == zipInputStream || null == zipOutputStream || null == bodyOs ) {
            return;
        }
        ZipEntry entryIn;
        try {
            while ((entryIn = zipInputStream.getNextEntry()) != null) {
                String entryName = entryIn.getName();
                ZipEntry entryOut = new ZipEntry(entryName);
                // 只使用 name
                zipOutputStream.putNextEntry(entryOut);
                if (entryName.equals(bodyname)) {
                    // 使用替换流 替换word内容
                    byte[] buf = bodyOs.toByteArray();
                    zipOutputStream.write(buf,0,buf.length);
                }
                else {
                    // 缓冲区
                    byte[] buf = new byte[8 * 1024];
                    int len;
                    // 输出普通Zip流
                    while ((len = (zipInputStream.read(buf))) > 0) {
                        zipOutputStream.write(buf, 0, len);
                    }
                }
                // 关闭此 entry
                zipOutputStream.closeEntry();

            }
        } catch (IOException e) {
            logger.error("zip文件的zip输入流失败:", e);
        } finally {
            close(bodyOs);
            close(zipInputStream);
            close(zipOutputStream);
        }
    }
    /**
     * 包装输入流
     */
    public static ZipInputStream wrapZipInputStream(InputStream inputStream) {
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        return zipInputStream;
    }

    /**
     * 包装输出流
     */
    public static ZipOutputStream wrapZipOutputStream(OutputStream outputStream) {
        ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
        return zipOutputStream;
    }

    private static void close(InputStream inputStream) {
        if (null != inputStream) {
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error("关闭流失败:", e);
            }
        }
    }

    private static void close(OutputStream outputStream) {
        if (null != outputStream) {
            try {
                outputStream.flush();
                outputStream.close();
            } catch (IOException e) {
                logger.error("关闭流失败:", e);
            }
        }
    }

    /**
     * 获取绝对路径
     * @return
     */
    public static String systemUrl(){
        if(System.getProperties().getProperty("os.name").toUpperCase().indexOf("WINDOWS") != -1){
            return "D:";
        }
        return "/temp";
    }

    public static  void wordAndDoc(Map<String, Object> dataMap,ByteArrayOutputStream byteArrayOutputStream) throws IOException {
        //word body
        String bodyName = "gtwjtest.ftl";
        ByteArrayOutputStream bodyOs =  writeFile(bodyName,dataMap);
        ZipInputStream zipInputStream = ZipUtils.wrapZipInputStream(ZipUtils.class.getResourceAsStream("/wordTemplates/gtwj.zip"));
        ZipOutputStream zipOutputStream = ZipUtils.wrapZipOutputStream(byteArrayOutputStream);
        ZipUtils.replaceItem(zipInputStream, zipOutputStream, bodyOs);

    }

    public static  void word(Map<String, Object> dataMap,ByteArrayOutputStream byteArrayOutputStream) throws IOException {
        //word body
        String bodyName = "gtwj.ftl";
        ByteArrayOutputStream bodyOs =  writeFile(bodyName,dataMap);
        ZipInputStream zipInputStream = ZipUtils.wrapZipInputStream(ZipUtils.class.getResourceAsStream("/wordTemplates/gtwj.zip"));
        ZipOutputStream zipOutputStream = ZipUtils.wrapZipOutputStream(byteArrayOutputStream);
        ZipUtils.replaceItem(zipInputStream, zipOutputStream, bodyOs);

    }
    public static  String wordFile(Map<String, Object> dataMap,String docxUrl) throws IOException {
        String bodyName = "gtwj.ftl";
        ByteArrayOutputStream bodyOs =  writeFile(bodyName,dataMap);
        ZipInputStream zipInputStream = ZipUtils.wrapZipInputStream(ZipUtils.class.getResourceAsStream("/wordTemplates/gtwj.zip")); //D:\zip\月度用电报告.zip
        ZipOutputStream zipOutputStream = ZipUtils.wrapZipOutputStream(new FileOutputStream(new File(docxUrl)));
        ZipUtils.replaceItem(zipInputStream, zipOutputStream, bodyOs);
        return docxUrl;
    }
    /**
     * @Description  生成带数据的模板
     * @Param
     */
    public static  ByteArrayOutputStream writeFile(String templateName,Map<String, Object> dataMap) throws IOException {
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);
        configuration.setClassForTemplateLoading(ZipUtils.class, "/wordTemplates/");
        Template template = configuration.getTemplate(templateName);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        Writer out = new BufferedWriter(new OutputStreamWriter(os),10240);
        try {
            template.process(dataMap,out);
        } catch (TemplateException e) {
            logger.error("生成带数据的模板失败:", e);
        }finally {
            if(out != null ){
                out.close();
            }
        }
        return os;
    }
    /**
     * @Description  生成带数据的模板
     * @Param
     */
    public static  void writeFile(String outFilePath,String templateName,Map<String, Object> dataMap) throws IOException {
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);

        configuration.setClassForTemplateLoading(ZipUtils.class, "/ftl");
        Template template = configuration.getTemplate(templateName);
        File docFile = new File(outFilePath);
        FileOutputStream fos = new FileOutputStream(docFile);
        Writer out = new BufferedWriter(new OutputStreamWriter(fos),10240);
        try {
            template.process(dataMap,out);
        } catch (TemplateException e) {
            logger.error("生成带数据的模板失败:", e);
        }finally {
            if(out != null ){
                out.close();
            }
        }
    }
    /**
     * @Description 判断文件夹是否存在 不存在就创建
     * @Param:
     * @return:
     */
    private static void isChartPathExist(String dirPath) {
        File file = new File(dirPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        System.out.println(file.exists()+"  dirPath  "+dirPath);
    }
    public static void main(String[] args) {
//        String templatePath =ZipUtils.class.getResource("/").getPath()+ "/ftl";
//        System.out.println(templatePath);
//        isChartPathExist("D:\\zip\\123");
        File file = new File("F:\\word\\gtwj.pdf");
        if(file.exists()){
            if(file.isFile()){
                boolean b = file.delete();
                if (b) {
                    logger.info("成功");
                }
            }
        }
    }
}

四、项目里引入jar包如下:

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

五、我用到的方法 ZipUtils.word(map, byteArrayOutputStream);其中map就是变量。