SpringBoot使用Freemarker导出word模板(OpenXML)

1、OpenXML

word.docx文档另存为xml之后会生成带有OpenXML标签的文档。

1.1、常用标签示意

标签 解释
XML文档开头描述,包括各种命名空间的描述






中,包含的所有文档主体标签
文档体
中,描述具体文档体
中,描述文档样式,注:出现多个时可能会导致莫名其妙的分页
表示真正的文本内容的意思是无内容时空格会被忽略
段落
  样式串,指明它包括的文本的显示样式
页眉
  页脚
一个值
中的标签,是r标签内的样式
中的标签,是p标签内的样式
在样式标签内,描述字体问粗体
在样式标签内,描述段落对齐方式为右对齐,可选值有右对齐rignt、左对齐left、居中对齐center、两端对齐both
在样式标签内,描述表格中的单元格上下对齐方式,可选值有:上top、中center、下bottom
在样式标签内,描述字号大小,sz表示Non-Complex Script Font Size,简单理解的话,就是单字节字符(如ASCII编码字符等)的大小
字号,szCs表示Complex Script Font Size,可以简单理解为双字节字符(如中日韩文字、阿拉伯文等)的大小
自定义XML属性

书签开始、结束
复合字体加粗
在样式标签内,描述字体
在样式标签内的w:rFonts标签内使用:

描述文档整个的样式
样式标签下表示视图比例100%
样式标签下表示文档视图是"print"
表格标签
中,表示表格样式标签
中,表示表格边框样式
中,定义表格列数以
中,定义表格每列的宽度
中,表示表格的行
中,表示表格行的样式
中,表示表格的某一行的某个单元格
中,描述单元格样式
左右合并单元格

上下合并单元格,合并的第一个单元格w:val="restart",下面需要合并的单元格都使用continue
分页符
图片区域
中,图片源(注:base64图片数据不带【data:image/png;base64,】前缀)
base64图片数据

图片引用占位符,引用的是图片(


    
    
    
    
    

1.2、文档大略结构




    
        
        xxx
        
        xxx
        
        xxx
        
        xxx
        
        0
        
        0
        
        0
        
        0
        
        0
        
        0
        
        0
        
        14
    
    
        
        xxxx
        xxxx
    
    
    
        
        
            
            
            
            
            
        
    
    
    
        
            
        
        
            
            
                
            
            
                
                
                
                
            
        
    
    
    
        
        
            
        
    
    
    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
        
    
    
    
        
        
            
                
                    
                    
                    
                        
                        
                        
                        
                        
                    
                
                
                    
                        
                        
                        
                        
                        
                    
                    xxx
                
            
        
        
            
            
                
                
                
                
            
        
    

2、SpringBoot使用FreeMarker模板导出自定义样式的文档

1、新建Word,里面插入个Table

SpringBoot使用Freemarker导出word模板(OpenXML)_第1张图片

2、另存为xml文件

3、格式化xml文件并重命名为ftl后缀

可以使用在线格式化工具:在线 XML 格式化 | 菜鸟工具 (runoob.com)

4、修改ftl文件

将ftl文件中1,2,3单元格位置变成${param1},${param2},${param3}

 5、java代码

这里使用SpringBoot2.7.4

5.1、添加pom依赖



	org.freemarker
	freemarker
	2.3.32

5.2、application配置

【application.properties改成application.yml方便一些】

server:
  port: 9090
spring:
  #freemarker配置
  #默认的classpath:/templates/?
  freemarker:
    template-loader-path: /ftl_templates
    #后缀
    suffix: .ftl
    #编码
    charset: utf-8
    #RequestContext
    request-context-attribute: request

5.3、工具类WordUtil

import freemarker.template.Configuration;
import freemarker.template.Template;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import java.io.*;
import java.net.URLEncoder;
import java.util.Map;

public class WordUtil {

    /**
     * 生成word文件
     */
    @SuppressWarnings("unchecked")
    public static void createWord(HttpServletResponse response, Map dataMap, String templateName, String fileName, String fileSuffix){
        File outFile=null;
        Writer out=null;
        InputStream fin=null;
        ServletOutputStream out2=null;
        try {
            //创建配置实例
            Configuration configuration = new Configuration(Configuration.getVersion());
            //设置编码
            configuration.setDefaultEncoding("UTF-8");
            //ftl模板文件 取模板文件存放地址
            configuration.setClassForTemplateLoading(WordUtil.class,"/ftl_templates");
            //获取模板
            Template template = configuration.getTemplate(templateName);
            //创建临时文件
            outFile = File.createTempFile(fileName, fileSuffix);
            //获取临时文件目录方便后面使用
            String tempFilePath = outFile.getAbsolutePath();
            //将模板和数据模型合并生成文件
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));
            //生成文件 实际这里已经将文件生成在指定位置
            template.process(dataMap, out);

            //以下操作是将文件下载
            File file = new File(tempFilePath);
            fin = new FileInputStream(file);
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            // 设置浏览器以下载的方式,处理该文件名  ps:docx格式office可能存在打不开等问题
            fileName = URLEncoder.encode(fileName+fileSuffix, "utf-8");
            response.setHeader("Content-Disposition","attachment;filename="+fileName);
            out2 = response.getOutputStream();
            byte[] buffer = new byte[512];
            int bytesToRead = -1;
            // 通过循环将读入的Word文件的内容输出到浏览器中
            while ((bytesToRead = fin.read(buffer)) != -1) {
                out2.write(buffer, 0, bytesToRead);
            }
            //关闭流
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (fin != null) {
                    fin.close();
                }
                if (out2 != null) {
                    out2.close();
                }
                if(outFile!=null) {
                    outFile.delete();
                }
            }catch (Exception e){

            }
        }
    }
}

5.4、Controller类

import com.example.ftldemo.utils.WordUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/demo")
public class DemoController {

    @RequestMapping("/export")
    public void exportDemo(HttpServletResponse response){
        /** 用于组装word页面需要的数据 */
        Map dataMap = new HashMap<>();
        dataMap.put("param1","111");
        dataMap.put("param2","222");
        dataMap.put("param3","333");
        String fileName = "生成Word文档";
        String fileSuffix=".doc";
        /** 生成word  数据包装,模板名,文件生成路径,生成的文件名*/
        WordUtil.createWord(response,dataMap, "导出wordDemo.ftl", fileName, fileSuffix);
    }
}

5.5、运行使用浏览器

访问    localhost:9090/demo/export  可以下载示例word文档

你可能感兴趣的:(技术分享,java,FreeMarker,Word)