SSM项目开发实战踩坑

SSM/Springboot实现导出docx文档

  1. 项目使用poi-tl实现导出word功能:获取数据录入到固定的word模板,最后生成新的word文档。

    Poi-tl官方文档:http://deepoove.com/poi-tl/

  • poi-tl介绍

poi-tl(poi template language)是Word模板引擎,基于Microsoft Word模板和数据生成新的文档。
Apache
POI不仅在上层封装了易用的文档API(文本、图片、表格、页眉、页脚、图表等),也可以在底层直接操作文档XML结构,poi-tl正是一个基于Apache
POI的Word模板引擎,并且拥有着让人喜悦的特性。

  • poi-tl语法:总共就5种语法:

1.文本模板{{var}} 渲染为 TextRenderData 或 String 数据模型

2.图片模板{{@photo}} 渲染为 PictureRenderData 数据模型

3.表格模板{{#var}} 渲染数据模型是 MiniTableRenderData

4.列表模板{{*var}} 渲染为 NumbericRenderData 数据模型

5.文档模板{{+var}} 渲染为 DocxRenderData 数据模型

  • poi-tl的优点

根据官方文档介绍,poi-tl具有以下优点: A、支持动态填充文本、图片、表格、列表、文档 B、支持DOCX格式,所有的模板标签都是以 {{
开头,以 }}结尾,模板标签可以出现在任何非文本框的位置,包括页眉,页脚,表格内部等等。
C、poi-tl的一个核心特点是数据模型与样式的分离,同样的数据模型可以用来渲染各种不同样式的模板。
D、文档的样式继承模板标签的样式,即如果模板{{title}}是蓝色微软雅黑加粗四号字体,则替换后的文本也是蓝色微软雅黑加粗四号字体。

  • 具体使用
    • 引入依赖
<!-- word导出 -->
<!-- poi-tl是基于Apache POI的Word模板引擎。poi-tl依赖的是poi3.16版本 -->
<dependency>
    <groupId>com.deepoove</groupId>
	<artifactId>poi-tl</artifactId>
	<version>1.5.0</version>
</dependency>

<!-- 对JSP的支持 -->
<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
	<groupId>org.apache.tomcat.embed</groupId>
	<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>jstl</artifactId>
</dependency>
  • WordUtil 工具类
import com.deepoove.poi.XWPFTemplate;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

/**
 * word工具类
 * Poi-tl模板引擎官方文档:http://deepoove.com/poi-tl/
 */
public class WordUtil {

    /**
     * 根据模板填充内容生成word,并下载
     * @param templatePath word模板文件路径
     * @param paramMap     替换的参数集合
     */
    public static void downloadWord(OutputStream out,String templatePath, Map<String, Object> paramMap) {
        
        Long time = new Date().getTime();
        // 生成的word格式
        String formatSuffix = ".docx";
        // 拼接后的文件名
        String fileName = time + formatSuffix;
		
		//设置生成的文件存放路径,可以存放在你想要指定的路径里面,临时存放文件,用浏览器下载存放到浏览器下载路径
		String rootPath="D:/mimi/"+File.separator+"file/word/"; 
		
		String filePath = rootPath+fileName;
		File newFile = new File(filePath);
		//判断目标文件所在目录是否存在
		if(!newFile.getParentFile().exists()){
			//如果目标文件所在的目录不存在,则创建父目录
			newFile.getParentFile().mkdirs();
		}
    			
        // 读取模板templatePath并将paramMap的内容填充进模板,即编辑模板(compile)+渲染数据(render)
        XWPFTemplate template = XWPFTemplate.compile(templatePath).render(paramMap);
        try {
        	//out = new FileOutputStream(filePath);//输出路径(下载到指定路径)
            // 将填充之后的模板写入filePath
            template.write(out);//将template写到OutputStream中
        	out.flush();
        	out.close();
        	template.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
  • 创建模板,把模板docx文件放到项目某个文件夹下
    在这里插入图片描述
    在这里插入图片描述
  • 编写一个controller 类,导出员工信息的接口类,供页面请求
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 导出Word
 * @author Administrator
 *
 */
@RequestMapping("/auth/exportWord/")
@RestController
public class ExportWordController {

	/**
	 * 用户信息导出word
	 * @throws IOException 
	 */
	@RequestMapping("/exportUserWord")
	public void exportUserWord(HttpServletRequest request,HttpServletResponse response) throws IOException{
		response.setContentType("application/vnd.ms-excel");  
        response.setHeader("Content-Disposition", "attachment;filename=" +new SimpleDateFormat("yyyyMMddHHmm").format(new Date())+".docx"); //导出的docx文件的文件名,以日期的形式
		Map<String, Object> params = new HashMap<>();
        // 以静态数据,渲染文本,可通过对象动态获取
        params.put("name", "张三");
        params.put("position", "开发工程师");
        params.put("entry_time", "2020-07-30");
        params.put("province", "江苏省");
        params.put("city", "南京市");
        // 渲染图片,传入本地图片,要想传入网上图片或Java图片可参考POI官网
        params.put("picture", new PictureRenderData(120, 120, "D:\\cssTest\\square.png"));
        // TODO 渲染其他类型的数据请参考官方文档
        String templatePath = "template/menzhen.docx";//模板文件位置
        
		WordUtil.downloadWord(response.getOutputStream(), templatePath, params);
	}
}
  1. SpringBoot 项目使用easypoi实现导出word功能
    easypoi官方文档:http://easypoi.mydoc.io/#category_49974
  • 引入easypoi依赖
<!-- word导出  方式二:easypoi-->
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-base</artifactId>
    <version>3.0.3</version>
</dependency>
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-web</artifactId>
    <version>3.0.3</version>
</dependency>
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-annotation</artifactId>
    <version>3.0.3</version>
</dependency>
  • 封装工具类
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.util.Assert;

import cn.afterturn.easypoi.word.WordExportUtil;

/**
 * word工具类
 * easypoi官方文档:http://easypoi.mydoc.io/#category_49974
 */
public class WordUtil2 {

	 /**
     * 导出word
     * <p>第一步生成替换后的word文件,只支持docx</p>
     * <p>第二步下载生成的文件</p>
     * <p>第三步删除生成的临时文件</p>
     * 模版变量中变量格式:{{foo}}
     * @param templatePath word模板地址
     * @param temDir 生成临时文件存放地址
     * @param fileName 文件名
     * @param params 替换的参数
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     */
    public static void exportWord(String templatePath, String temDir, String fileName, Map<String, Object> params, HttpServletRequest request, HttpServletResponse response) {
        Assert.notNull(templatePath,"模板路径不能为空");
        Assert.notNull(temDir,"临时文件路径不能为空");
        Assert.notNull(fileName,"导出文件名不能为空");
        Assert.isTrue(fileName.endsWith(".docx"),"word导出请使用docx格式");
        if (!temDir.endsWith("/")){
            temDir = temDir + File.separator;
        }
        File dir = new File(temDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        try {
            String userAgent = request.getHeader("user-agent").toLowerCase();
            if (userAgent.contains("msie") || userAgent.contains("like gecko")) {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } else {
                fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1");
            }
            XWPFDocument doc = WordExportUtil.exportWord07(templatePath, params);
            String tmpPath = temDir + fileName;
            FileOutputStream fos = new FileOutputStream(tmpPath);
            doc.write(fos);
            // 设置强制下载不打开
            response.setContentType("application/force-download");
            // 设置文件名
            response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
            OutputStream out = response.getOutputStream();
            doc.write(out);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        	delFileWord(temDir,fileName);//这一步看具体需求,要不要删
        }

    }
    
    /**
     * 删除零时生成的文件
     */
    public static void delFileWord(String filePath, String fileName) {
        File file = new File(filePath + fileName);
        File file1 = new File(filePath);
        file.delete();
        file1.delete();
    }
} 
  • 创建模板

在这里插入图片描述

注意区分: easypoi:word模板的文本格式填充项 是 {{}},图片也是 {{}}
poi-tl:word模板的文本格式填充项是{{}},而图片是 {{@}}

  • 创建Controller进行调用
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import com.deepoove.poi.data.PictureRenderData;
import com.example.mimiprogram.common.WordUtil;
import com.example.mimiprogram.common.WordUtil2;

import cn.afterturn.easypoi.word.entity.WordImageEntity;

/**
 * 导出Word
 * @author Administrator
 *
 */
@RequestMapping("/auth/exportWord/")
@RestController
public class ExportWordController {

	/**
	 * 用户信息导出word  --- easypoi
	 * @throws IOException 
	 */
	@RequestMapping("/exportUserWord2")
	public void exportUserWord2(HttpServletRequest request,HttpServletResponse response) throws IOException{
		Map<String, Object> params = new HashMap<>();
		/*//如果word模板地址放在 webapp下采用如下方式获取word模板路径:
		//表示到项目的根目录(webapp)下,要是想到目录下的子文件夹,修改"/"即可
		String path = request.getSession().getServletContext().getRealPath("/");*/
		
		//word模板地址放在src/main/resources/下,因为配置过静态资源映射,所以采用如下方式获取项目中的word模板地址:
		String templatePath ="static/template/user2.docx";//word模板地址
		
		// 渲染文本
		params.put("name", "张三");
		params.put("position", "开发工程师");
		params.put("entry_time", "2020-07-30");
		params.put("province", "江苏省");
		params.put("city", "南京市");
		
		// 渲染图片
		WordImageEntity image = new WordImageEntity();
        image.setHeight(120);
        image.setWidth(120);
        image.setUrl("D:\\cssTest\\square.png");
        image.setType(WordImageEntity.URL);
        params.put("picture", image);
		// TODO 渲染其他类型的数据请参考官方文档
        
		
		String temDir="D:/mimi/"+File.separator+"file/word/"; ;//生成临时文件存放地址
		
		//生成文件名
		Long time = new Date().getTime();
        // 生成的word格式
        String formatSuffix = ".docx";
        // 拼接后的文件名
        String fileName = time + formatSuffix;//文件名  带后缀
        //导出word
		WordUtil2.exportWord(templatePath, temDir, fileName, params, request, response);
	}
}

需要注意工具类WordUtil中:
downloadWord方法中的一行代码:

out = new FileOutputStream(filePath);//输出路径(下载到指定路径)

1 exportUserWord方法中的两行代码:

//浏览器下载

response.setContentType("application/vnd.ms-excel");  
response.setHeader("Content-Disposition", "attachment;filename=" +new SimpleDateFormat("yyyyMMddHHmm").format(new Date())+".docx");

如果想要显示浏览器下载,exportUserWord方法中的这两行代码必须显示,而downloadWord方法中的那一行代码必须隐藏。

如果想要下载到指定的路径,exportUserWord方法中的这两行代码必须隐藏,而downloadWord方法中的那一行代码必须显示。

SSM+layui实现数据表格

SSM/Springboot+layui实现数据表格

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值