poi-tl 的模板导出工具
1. demo示例
@Override
public void downloadDocxFileDeactivateForm(HttpServletResponse response, String deactivateNumber) {
List<Map<String, Object>> flowList = deactivateList.stream().map(this::mapDeactivateList).collect(Collectors.toList());
Map<String, Object> objectMap = new HashMap<>();
objectMap.put("yby7", deactivate.getDeactivateRemark());
objectMap.put("yby8", deactivate.getDeptName());
objectMap.put("yby9", SystemApiUtils.getUserName(deactivate.getCreateUserId()));
objectMap.put("yby10", DateUtil.formatDate(deactivate.getCreateTime()));
objectMap.put("fileList", flowList);
String templatePath = "exporttemplates/InstrumentAndEquipmentShutdownApplicationForm.docx";
String tempPath = SystemApiUtils.getConfigValue(CmtcConst.CONFIG_KEY.FILE_TEMP_PATH.getValue());
File printDir = new File(tempPath);
if (!printDir.exists()) {
printDir.mkdirs();
}
String newPath = printDir + File.separator + System.currentTimeMillis() + "申请单.docx";
PoiTlUtils.exportContainsTable(templatePath, newPath, objectMap, response, "fileList");
}
2. 工具类
/**
* poi-tl 工具类
*
* <p>
* 模版设置:
* 单元格填充 {{ key }}
* 表格循环填充
* 表头 {{ key }}
* 单元格 [ key ]
* 输出图片 [@path]
* </p>
**/
@Slf4j
public class PoiTlUtils {
/**
* 导出单元格内容
*
* @param templatePath 模板路径
* @param newWordPath 生成后的新路径
* @param resultMap 文档数据
*/
public static void export(String templatePath, String newWordPath, Map<String, Object> resultMap, HttpServletResponse response) {
exportDefault(templatePath, newWordPath, resultMap, true, true, response);
}
/**
* @param flag 是否自动删除文件
*/
public static void export(String templatePath, String newWordPath, Map<String, Object> resultMap, boolean flag, HttpServletResponse response) {
exportDefault(templatePath, newWordPath, resultMap, flag, true, response);
}
/**
* 是否自动导出
*/
public static void export(String templatePath, String newWordPath, Map<String, Object> resultMap, boolean flag, boolean exportDefault, HttpServletResponse response) {
exportDefault(templatePath, newWordPath, resultMap, flag, exportDefault, response);
}
public static void exportDefault(String templatePath, String newWordPath, Map<String, Object> resultMap, boolean flag, boolean exportDefault, HttpServletResponse response) {
try {
// 用流读取jar包模板的路径,再复制此模板文件
fileCopy(templatePath, newWordPath);
XWPFTemplate template = XWPFTemplate.compile(newWordPath).render(resultMap);
// 暂存在本地
FileOutputStream out = new FileOutputStream(newWordPath);
template.write(out);
template.close();
out.flush();
out.close();
log.info("模板填充导出新路径: {} \n, 参数: {}", newWordPath, resultMap);
if (exportDefault) {
exportResponse(newWordPath, flag, response);
}
} catch (Exception e) {
log.error("模板填充导出新路径: {} \n, 参数: {}", newWordPath, resultMap);
log.error("POI-TL导出失败: {0}", e);
}
}
public static void exportToPath(String templatePath, String newWordPath, Map<String, Object> resultMap, HttpServletResponse response) {
try {
// 用流读取jar包模板的路径,再复制此模板文件
fileCopy(templatePath, newWordPath);
XWPFTemplate template = XWPFTemplate.compile(newWordPath).render(resultMap);
// 暂存在本地
FileOutputStream out = new FileOutputStream(newWordPath);
template.write(out);
template.close();
out.flush();
out.close();
log.info("模板填充导出新路径: {} \n, 参数: {}", newWordPath, resultMap);
} catch (Exception e) {
log.error("模板填充导出新路径: {} \n, 参数: {}", newWordPath, resultMap);
log.error("POI-TL导出失败: {0}", e);
}
}
/**
* 导出单元格内容并且包含表格
*
* @param templatePath 模板路径
* @param newWordPath 生成后的新路径
* @param resultMap 文档数据
* @param isExportResponse 是否导出浏览器
* @param binds 表格循环名称
*/
public static void exportContainsTable(String templatePath, String newWordPath, Map<String, Object> resultMap,
boolean isExportResponse, HttpServletResponse response, String... binds) {
try {
// 创建一个列表的规则
HackLoopTableRenderPolicy policy = new HackLoopTableRenderPolicy();
// 设置列表配置,如果有多个列表时需加.bind("", policy) 新列表配置即可
ConfigureBuilder newBuilder = Configure.newBuilder();
for (String bind : binds) {
newBuilder.bind(bind, policy);
}
Configure build = newBuilder.build();
// 用流读取jar包模板的路径,再复制此模板文件
fileCopy(templatePath, newWordPath);
XWPFTemplate template = XWPFTemplate.compile(newWordPath, build).render(resultMap);
// 暂存在本地
FileOutputStream out = new FileOutputStream(newWordPath);
template.write(out);
template.close();
out.flush();
out.close();
if (isExportResponse) {
exportResponse(newWordPath, true, response);
}
} catch (Exception e) {
log.error("POI-TL导出失败: {0}", e);
}
}
/**
* 默认导出浏览器
*/
public static void exportContainsTable(String templatePath, String newWordPath, Map<String, Object> resultMap, HttpServletResponse response, String... binds) {
exportContainsTable(templatePath, newWordPath, resultMap,true, response, binds);
}
/**
* 不导出
*/
public static void exportContainsTableNotExportResponse(String templatePath, String newWordPath, Map<String, Object> resultMap, HttpServletResponse response, String... binds) {
exportContainsTable(templatePath, newWordPath, resultMap,false, response, binds);
}
/**
* 导出图片
*
* @param width 宽度
* @param height 高度
* @param format 图片后缀
* @param fileType 文件类型
*/
public static Object exportImage(int width, int height, String format, Object fileType, String altMeta) {
if (format == null) {
format = ".png";
}
BufferedImage urlBufferedImage;
if (fileType instanceof String) {
// 导出网络图片
urlBufferedImage = BytePictureUtils.getUrlBufferedImage(String.valueOf(fileType));
} else if (fileType instanceof File) {
// 导出File图片地址
urlBufferedImage = BytePictureUtils.getLocalBufferedImage((File) fileType);
} else {
throw new RuntimeException("File Type 不存在");
}
PictureRenderData pictureRenderData = new PictureRenderData(width, height, format, urlBufferedImage);
// 设置图片alt,如果图片出问题,可以显示alt
pictureRenderData.setAltMeta(altMeta);
return pictureRenderData;
}
/**
* 导出渲染图片信息
*
* @param format 图片后缀
* @param fileType 图片流
*/
public static Object exportImage(String format, Object fileType) {
return exportImage(30, 20, format, fileType,"");
}
/**
* 导出渲染图片信息
*
* @param fileType 图片流
*/
public static Object exportImage(Object fileType) {
return exportImage(30, 20, null, fileType, "");
}
/**
* 自定义altMeta
*
* @param fileType 图片流
*/
public static Object exportImage(Object fileType, String altMeta) {
return exportImage(30, 20, null, fileType,altMeta);
}
public static Object exportImage(int width, int height, Object fileType) {
return exportImage(width, height, null, fileType, "");
}
/**
* 下载到浏览器导出
*/
public static void exportResponse(String newWordPath, boolean flag, HttpServletResponse response) throws IOException {
// 下载到客户端
InputStream stream = Files.newInputStream(Paths.get(newWordPath));
byte[] b = new byte[1024];
int length;
while ((length = stream.read(b)) > 0) {
response.getOutputStream().write(b, 0, length);
}
stream.close();
if (flag) {
FileUtils.deleteFile(newWordPath);
}
}
public static void exportResponse(String newWordPath, HttpServletResponse response) throws IOException {
exportResponse(newWordPath, true, response);
}
/**
* 复制文件
*/
public static void fileCopy(String templatePath, String dest) {
File destFile = new File(dest);
// 准备输入输出流
InputStream in = PoiTlUtils.class.getClassLoader().getResourceAsStream(templatePath);
OutputStream out = null;
try {
out = Files.newOutputStream(destFile.toPath());
byte[] flush = new byte[1024];
int len = -1;
while ((len = in.read(flush)) != -1) {
out.write(flush, 0, len);
}
} catch (IOException e) {
log.error("文件复制异常:{0}", e);
} finally {
// 关闭原则,先用后关
// 关闭输出流
if (out != null) {
try {
out.close();
} catch (IOException e) {
log.error("关闭输出流异常:{0}", e);
}
}
// 关闭输入流
if (in != null) {
try {
in.close();
} catch (IOException e) {
log.error("关闭输入流异常:{0}", e);
}
}
}
}
}