poi导出word表格、图片、多段等处理
全文介绍
poi-tl(poi template language)是Word模板引擎,使用Word模板和数据创建很棒的Word文档 。
常用标签介绍(官网):
1文本:{{var}} 2. 图片:{{@var}}
3表格:{{#var}} 4. 列表:{{*var}}
5区块对:{{?sections}}{{/sections}} 6. 嵌套:{{+var}}
本次制作的Demo,简写代码、多注释,只为容易理解,读者可根据自己需求进行重构代码、优化代码。
1根据{{table}}、[content],实现word表格导出(有模板)
2根据{{?sections}}{{/sections}},多个表格段落进行表格、图片插入
环境配置
com.deepoove poi-tl 1.10.0 io.github.draco1023 poi-tl-ext 0.4.2
1根据{{table}}、[content],实现word表格导出(有模板)
1.1模板

模板在代码中位置

1.2代码实现
//测试类实现
public class ExportWordTest7 {
@Test
void exportWord() throws IOException {
//1 获取模板文件流
InputStream resourceAsStream = this.getClass().getResourceAsStream("/templates/pmwordBg.docx");
//2 word数据集合
Map params = new HashMap();
params.put("workContentss",getDynamicFlag1());
//3 图片指定插件
ConfigureBuilder builder = Configure.builder();
Configure config = builder.build();
HackLoopTableRenderPolicy policy = new HackLoopTableRenderPolicy();
config.customPolicy("workContentss", policy);
//4 word导出
//本地测试
String filePath = FileUtil.getProjectPath() + "document" + File.separator + "牧羊人导出实例.docx";
dynamicExport(params,new File(filePath),resourceAsStream,config,null,false);
//浏览器文件名称设置
// String fileName = wordExportPmProtermVo.getProjectName()+"第"+wordExportPmProtermVo.getJournalTerm()+"期" + ".docx";
}
/**
* @param data 填充数据
* @param filePath 临时路径
* @param resource 模板路径
* @param response 通过浏览器下载需要
* @param isBrowser true-通过浏览器下载 false-下载到临时路径
*/
public void dynamicExport(Map data, File filePath, InputStream resource, Configure config, HttpServletResponse response, boolean isBrowser){
try {
if (Boolean.FALSE.equals(isBrowser)) {//本地
File parentFile = filePath.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
FileOutputStream out = new FileOutputStream(filePath);
XWPFTemplate.compile(resource, config).render(data).writeAndClose(out);
} else {//浏览器
ServletOutputStream out = response.getOutputStream();
XWPFTemplate.compile(resource, config).render(data).writeAndClose(out);
}
}catch (Exception e) {
e.printStackTrace();
}
}
/**
* @Description: 一、本日主要工作数据整理
* @Author: syq
* @Date: 2023/4/6 18:31
*/
public List<Map> getDynamicFlag1(){
List<Map> dynamicFlag = new ArrayList();
for (int i = 0; i < 4; i++) {
Map dynamicTableMap = new HashMap();
dynamicTableMap.put("xh", i+1);//序号
dynamicTableMap.put("workContent", "工作内容");//专业主要工作
dynamicTableMap.put("professional", "专业");//专业
dynamicTableMap.put("inspectedBy", "检查人");//检查人
dynamicFlag.add(dynamicTableMap);
}
return dynamicFlag;
}
}
/**
* @author: muyangren
* @Date: 2023/1/14
* @Description: com.muyangren.utils
* @Version: 1.0
*/
public class FileUtil {
/**
* 创建FileItem
* @param file
* @param fieldName
* @return
*/
public static MultipartFile createFileItem(File file, String fieldName) {
FileItemFactory factory = new DiskFileItemFactory(16, null);
FileItem item = factory.createItem(fieldName, ContentType.MULTIPART_FORM_DATA.toString(), true, file.getName());
int bytesRead = 0;
byte[] buffer = new byte[8192];
try {
FileInputStream fis = new FileInputStream(file);
OutputStream os = item.getOutputStream();
while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
return new CommonsMultipartFile(item);
}
/**
* 下载到本地路径
* @param file
* @return
* @throws IOException
*/
public static File fileDownloadToLocalPath(MultipartFile file) {
File destFile = null;
try {
//获取文件名称
if (StringUtils.isEmpty(file.getOriginalFilename())){
throw new ServerException("导入模板失败!");
}
String fileName = file.getOriginalFilename();
//获取文件后缀
String pref = fileName.lastIndexOf(".") != -1 ? fileName.substring(fileName.lastIndexOf(".") + 1) : null;
//临时文件
//临时文件名避免重复
String uuidFile = UUID.randomUUID().toString().replace("-", "") + "." + pref;
destFile = new File(FileUtil.getProjectPath() + uuidFile);
if (!destFile.getParentFile().exists()) {
destFile.getParentFile().mkdirs();
}
file.transferTo(destFile);
} catch (IOException e) {
e.printStackTrace();
}
return destFile;
}
/**
* @return 文件路径
*/
public static String getProjectPath(){
String os = System.getProperty("os.name").toLowerCase();
//windows下
if (os.indexOf("windows")>=0) {
return "C://temp/";
}else{
return "/usr/local/temp/";
}
}
1.3效果图

2根据{{?sections}}{{/sections}},多个表格段落进行表格、图片插入
2.1模板

2.2代码实现
package com.muyangren;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.muyangren.enums.StyleEnum;
import com.muyangren.utils.FileUtil;
import com.muyangren.utils.HtmlUtil;
import com.muyangren.vo.Attachment;
import com.muyangren.vo.Attachments;
import org.apache.commons.lang3.StringUtils;
import org.ddr.poi.html.HtmlRenderPolicy;
import org.junit.jupiter.api.Test;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
/**
* @Author: syq
* @Description: ${description}
* @Date: 2023/4/9 14:33
* @Version: 1.0
*/
public class ExportWordTest8 {
/**
* @Description: word按照指定模式进行导出
* 1 获取模板文件流
* 2 数据与word锚点匹配
* 3 图片指定插件
* 4 word导出
* @Author: syq
* @Date: 2023/4/6 17:22
*/
@Test
void exportWord() throws IOException {
//1 获取模板文件流
InputStream resourceAsStream = this.getClass().getResourceAsStream("/templates/pmwordtest.docx");
//2 word数据集合
Map params = new HashMap();
//2.3 数据与word锚点匹配
params.put("dynamicFlag1",getDynamicFlag1());
params.put("workTitle","工作概述");
//3 图片指定插件
HtmlRenderPolicy htmlRenderPolicy = new HtmlRenderPolicy();
ConfigureBuilder builder = Configure.builder();
Configure config = builder.build();
config.customPolicy("pictureUrl", htmlRenderPolicy);
//4 word导出
//本地测试
String filePath = FileUtil.getProjectPath() + "document" + File.separator + "牧羊人导出实例.docx";
dynamicExport(params,new File(filePath),resourceAsStream,config,null,false);
//浏览器文件名称设置
// String fileName = wordExportPmProtermVo.getProjectName()+"第"+wordExportPmProtermVo.getJournalTerm()+"期" + ".docx";
// try {
// response.setHeader("Content-disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
// } catch (UnsupportedEncodingException e) {
// e.printStackTrace();
// }
}
/**
* @param data 填充数据
* @param filePath 临时路径
* @param resource 模板路径
* @param response 通过浏览器下载需要
* @param isBrowser true-通过浏览器下载 false-下载到临时路径
*/
public void dynamicExport(Map data, File filePath, InputStream resource, Configure config, HttpServletResponse response, boolean isBrowser){
try {
if (Boolean.FALSE.equals(isBrowser)) {//本地
File parentFile = filePath.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
FileOutputStream out = new FileOutputStream(filePath);
XWPFTemplate.compile(resource, config).render(data).writeAndClose(out);
} else {//浏览器
ServletOutputStream out = response.getOutputStream();
XWPFTemplate.compile(resource, config).render(data).writeAndClose(out);
}
}catch (Exception e) {
e.printStackTrace();
}
}
/**
* @Description: 一、本日主要工作数据整理
* @Author: syq
* @Date: 2023/4/6 18:31
*/
public List<Map> getDynamicFlag1() throws IOException {
List<Map> dynamicFlag = new ArrayList();
for (int i = 0; i < 4; i++) {
Map dynamicTableMap = new HashMap();
dynamicTableMap.put("xh", i+1);//序号
dynamicTableMap.put("workContent", "工作内容");//专业主要工作
dynamicTableMap.put("professional", "专业");//专业
dynamicTableMap.put("inspectedBy", "检查人");//检查人
//url方式
// List list = new ArrayList();
// list.add("https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=%E5%9B%BE%E7%89%87&hs=0&pn=0&spn=0&di=7207123747399008257&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&ie=utf-8&oe=utf-8&cl=2&lm=-1&cs=1204793430%2C3263400171&os=3423103612%2C2074051226&simid=1204793430%2C3263400171&adpicid=0&lpn=0&ln=30&fr=ala&fm=&sme=&cg=&bdtype=0&oriquery=%E5%9B%BE%E7%89%87&objurl=https%3A%2F%2Fup.deskcity.org%2Fpic_source%2F2f%2Ff4%2F42%2F2ff442798331f6cc6005098766304e39.jpg&fromurl=ippr_z2C%24qAzdH3FAzdH3Fooo_z%26e3B1jfhvtpy_z%26e3B562AzdH3F15ogs5w1AzdH3Fdd9m0m-a-axa_z%26e3Bip4s&gsm=&islist=&querylist=&dyTabStr=MCwxLDYsMyw0LDUsMiw3LDgsOQ%3D%3D");
// dynamicTableMap.put("pictureUrl",dealWithPictureWidthAndHeight(getBase64String(list)));
//本地方式
File file = new File("C:/aa.png");
String baseString = base64String(file);
baseString = "data:image/jpeg;base64," + baseString;
String base = "
" ;
// "
"+
// "
";
// String base = "
"; dynamicTableMap.put("pictureUrl", dealWithPictureWidthAndHeight(base));//一张或多张图片 dynamicFlag.add(dynamicTableMap); } return dynamicFlag; } public String base64String(File file) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); FileInputStream fileInputStream = new FileInputStream(file); byte[] bytes = new byte[1024]; //用来定义一个准备接收图片总长度的局部变量 int len; //将流的内容读取到bytes中 while ((len = fileInputStream.read(bytes)) > 0) { //将bytes内存中的内容从0开始到总长度输出出去 out.write(bytes, 0, len); } //通过util包中的Base64类对字节数组进行base64编码 return Base64.getEncoder().encodeToString(out.toByteArray()); } /** * @Description: 根据url获取图片base64 * @Author: syq * @Date: 2023/4/7 16:37 */ public String getBase64String(List listPath){ String base64String = ""; for (int i = 0; i < listPath.size(); i++) { String address = listPath.get(i); if(StringUtils.isNotBlank(address)){ String get = netSourceToBase64(address, "GET"); if(StringUtils.isNotBlank(get)){ get = "data:image/jpeg;base64," + get; base64String = base64String + "
"; } } } return base64String; } public static String netSourceToBase64(String srcUrl, String requestMethod) { ByteArrayOutputStream outPut = new ByteArrayOutputStream(); byte[] data = new byte[1024 * 8]; try { // 创建URL URL url = new URL(srcUrl); // 创建链接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod(requestMethod); conn.setConnectTimeout(10 * 1000); if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) { //连接失败/链接失效/文件不存在 return null; } InputStream inStream = conn.getInputStream(); int len = -1; while (-1 != (len = inStream.read(data))) { outPut.write(data, 0, len); } inStream.close(); } catch (IOException e) { e.printStackTrace(); } // 对字节数组Base64编码 return Base64.getEncoder().encodeToString(outPut.toByteArray()); } /** * @Description: 图片处理 * @Author: syq * @Date: 2023/4/7 16:04 */ private String dealWithPictureWidthAndHeight(String content) { List<HashMap> imagesFiles = HtmlUtil.regexMatchWidthAndHeight(content); if (imagesFiles.size() > 0) { for (HashMap imagesFile : imagesFiles) { String newFileUrl = imagesFile.get(StyleEnum.NEW_FILE_URL.getValue()); String fileUrl = imagesFile.get(StyleEnum.FILE_URL.getValue()); if (newFileUrl != null) { content = content.replace(fileUrl, newFileUrl); } } } return content; }}
2.3效果图

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/fe464db376.html
