关于通过StringTemplate模板生成xml转成excel后office无法打开的问题解决
说明:本人最近在着手实现导出日志数据,由于日志数据过多,在网上查找java 导出大量数据到excel的例子。
后发现园子里某位老哥通过StringTemplate模板生成excel格式的xml,这个思路令我大为惊奇。
在融入到自己的项目后,发现wps可以正常打开生成的文件,但excel2019无法打开。
通过各种测试,后发现一种方法能解决这个问题。
老哥原文链接:【https://www.cnblogs.com/barrywxx/p/10700283.html】
没看过的先看看老哥的思路。
我这里只针对excel无法打开生成的文件做解决说明
第一步:列数写为固定的16384
/***
* 写入excel文件数据信息
* 一页写入
*/
public <T> void writeExcelOneSheetData(String sheetName, List<T> dataList) {
// 写入excel文件数据信息
// 列数
StringTemplate body = stGroup.getInstanceOf(templateSuffix + "body");
Worksheet worksheet = new Worksheet();
worksheet.setSheet(sheetName);
// 最重要的是这一行,将列数写为固定的16384,别问为什么,我也不知道!
worksheet.setColumnNum(16384);
worksheet.setRowNum(dataList.size() + 10);
worksheet.setRows(dataList);
body.setAttribute("worksheet", worksheet);
this.writer.print(body.toString());
this.writer.flush();
worksheet = null;
body = null;
Runtime.getRuntime().gc();
}
第二步:生成的文件后缀使用xls,不要使用xlsx。
而后使用excel打开,会弹出文件不安全提示,问是否继续打开?点击是。问题完美解决!
期间还试过对内容里的特殊符号进行转译处理,后来发现不用转译也能正常显示。不过还是把转译的贴出来,需要自取:
public static String xmlTranslation(String s) {
// 写之前对特殊字符串进行转义
//< <
// > >
// & &
// ' '
// " "
s = s.replace("&", "&");
s = s.replace("<", "<");
s = s.replace(">", ">");
s = s.replace("'", "'");
s = s.replace("\"", """);
return s;
}
这是我的完整代码,有需要自取:

package com.hz.plat.common.util; import com.hz.plat.common.entity.Worksheet;
import lombok.extern.slf4j.Slf4j;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup; import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.util.List; /**
* 类功能描述:generator big data Excel
*
* @author WangXueXing create at 19-4-13 下午10:23
* @version 1.0.0
*/
@Slf4j
public class ExcelGenerator { StringTemplateGroup stGroup = null;
PrintWriter writer = null; String templateSuffix = "Excel"; public ExcelGenerator() {
} public ExcelGenerator(String suffix, File file) {
this.templateSuffix = suffix;
this.stGroup = new StringTemplateGroup("test");
this.writer = writeExcelHead(file);
} /**
* 写入单个Sheet的Excel
*
* @param templatePrefix 模板前缀,默认两个模板后缀分别为head及body
* @param outFile 生成Excel文件
* @param sheetName 单个sheet名称
* @param dataList 填充数据列表
* @param <T> 填充对象泛型
* @throws FileNotFoundException
* @throws ClassNotFoundException
*/
public static <T> void writeExcelOneSheet(String templatePrefix, File outFile, String sheetName, Class clazz, List<T> dataList) {
long startTimne = System.currentTimeMillis();
StringTemplateGroup stGroup = new StringTemplateGroup(String.valueOf(startTimne));
// 写入excel文件头部信息
StringTemplate head = stGroup.getInstanceOf(templatePrefix + "head");
try (PrintWriter writer = new PrintWriter(new BufferedOutputStream(Files.newOutputStream(outFile.toPath())))) {
writer.print(head.toString());
writer.flush();
// excel单表最大行数是65535
Field[] fields = clazz.getDeclaredFields();
// 写入excel文件数据信息
StringTemplate body = stGroup.getInstanceOf(templatePrefix + "body");
Worksheet worksheet = new Worksheet();
worksheet.setSheet(sheetName);
worksheet.setColumnNum(fields.length + 2);
worksheet.setRowNum(10000 + 10);
worksheet.setRows(dataList);
body.setAttribute("worksheet", worksheet);
writer.print(body.toString());
writer.flush();
// 写入excel文件尾部
writer.print("</Workbook>");
writer.flush();
} catch (Exception e) {
log.error("写入Excel异常", e);
}
} public static String xmlTranslation(String s) {
// 写之前对特殊字符串进行转义
//< <
// > >
// & &
// ' '
// " "
s = s.replace("&", "&");
s = s.replace("<", "<");
s = s.replace(">", ">");
s = s.replace("'", "'");
s = s.replace("\"", """);
return s;
} /***
* 获取PrintWriter
*/
private PrintWriter writeExcelHead(File file) {
// 正式开始
try {
PrintWriter writer = new PrintWriter(new BufferedOutputStream(Files.newOutputStream(file.toPath())));
// 写入excel文件头部信息
StringTemplate head = stGroup.getInstanceOf(templateSuffix + "head");
writer.print(head.toString());
writer.flush();
// 头部信息写入完成
return writer;
} catch (Exception e) {
log.error("写入Excel异常", e);
}
return null;
} /***
* 写入excel文件数据信息
* 分页写入
*/
public <T> void writeExcelAssignSheetData(String sheetName, List<List<T>> dataList) {
// 写入excel文件数据信息
// 列数
for (int i = 0, dataListSize = dataList.size(); i < dataListSize; i++) {
List<T> x = dataList.get(i);
writeExcelOneSheetData(sheetName + "(" + (i + 1) + ")", x);
}
} /***
* 写入excel文件数据信息
* 一页写入
*/
public <T> void writeExcelOneSheetData(String sheetName, List<T> dataList) {
// 写入excel文件数据信息
// 列数
StringTemplate body = stGroup.getInstanceOf(templateSuffix + "body");
Worksheet worksheet = new Worksheet();
worksheet.setSheet(sheetName);
worksheet.setColumnNum(16384);
worksheet.setRowNum(dataList.size() + 10);
worksheet.setRows(dataList);
body.setAttribute("worksheet", worksheet);
this.writer.print(body.toString());
this.writer.flush();
worksheet = null;
body = null;
Runtime.getRuntime().gc();
} /***
* 写入excel文件尾部
*/
public void finishExcel() {
// 写入excel文件尾部
writer.print("</Workbook>");
writer.flush();
writer.close();
} }
关于通过StringTemplate模板生成xml转成excel后office无法打开的问题解决的更多相关文章
- NPOI根据模板生成chart图表导出Excel
导入NPOI的全部dll. 因为NPOI的API里面还没有对于Chart图表方面的操作,所以只能根据提示做好的图表作为模板,修改数据源的方法来改变图表. 注意:NPOI要用2003版以下的excel才 ...
- Html Table用JS导出excel格式问题 导出EXCEL后单元格里的000412341234会变成412341234 7-14 会变成 2018-7-14(7月14) 自定义格式 web利用table表格生成excel格式问题 js导出excel增加表头、mso-number-format定义数据格式 数字输出格式转换 mso-number-format:"\@"
Html Table用JS导出excel格式问题 我在网上找的JS把HTML Tabel导出成EXCEL.但是如果Table里的数字内容为0开的的导成Excel后会自动删除0,我想以text的格式写入 ...
- JAVAWEB使用FreeMarker利用ftl把含有图片的word模板生成word文档,然后打包成压缩包进行下载
这是写的另一个导出word方法:https://www.cnblogs.com/pxblog/p/13072711.html 引入jar包,freemarker.jar.apache-ant-zip- ...
- 使用freemarker生成xml模板
今天在java交流群里有个人问我如何用freemarker生成xml模板文件,可以手动配置参数,于是我到网上百度了一下.发现有一位同行的博文写的很nice,于是我就照着他的代码敲了一遍,最后实现了,本 ...
- Spring MVC-集成(Integration)-生成XML示例(转载实践)
以下内容翻译自:https://www.tutorialspoint.com/springmvc/springmvc_xml.htm 说明:示例基于Spring MVC 4.1.6. 以下示例说明如何 ...
- ASP.NET MVC 解析模板生成静态页一(RazorEngine)
简述 Razor是ASP.NET MVC 3中新加入的技术,以作为ASPX引擎的一个新的替代项.在早期的MVC版本中默认使用的是ASPX模板引擎,Razor在语法上的确不错,用起来非常方便,简洁的语法 ...
- NET MVC RazorEngine 解析模板生成静态页
ASP.NET MVC 解析模板生成静态页一(RazorEngine) 简述 Razor是ASP.NET MVC 3中新加入的技术,以作为ASPX引擎的一个新的替代项.在早期的MVC版本中默认使用的是 ...
- T4模板生成代码。 数据实体层与数据仓储层。备注
文件生成模板:TempleteManager.ttinclude <#@ assembly name="System.Core" #><#@ assembly n ...
- freemarker根据模板生成word文件实现导出功能
一.准备工作 1.创建一个03的word文档,动态的数据用占位符标志占位(如testname).然后另存为word2003的xml文件. 2.格式化xml文件,占位符的位置用${testname}代替 ...
- java通过FreeMarker模板生成Excel文件之.ftl模板制作
关于怎么通过freemarker模板生成excel的文章很多,关键点在于怎么制作模板文件.ftl 网上的办法是: (1)把Excel模板的格式调好,另存为xml文件 (2)新建一个.ftl文件,把xm ...
随机推荐
- 2023-07-12:RocketMQ如何做到消息不丢失?
2023-07-12:RocketMQ如何做到消息不丢失? 答案2023-07-12: RocketMQ通过刷盘机制.消息拉取机制和ACK机制等多种方式来确保消息投递的可靠性,防止消息丢失. 1.刷盘 ...
- Federated Learning001
联邦学习--笔记001 2022.11.16周三 今天学习了联邦学习的开山之作---Communication-Efficient Learning of Deep Networks from Dec ...
- 《最新出炉》系列入门篇-Python+Playwright自动化测试-8-上下文(Context)
1.简介 其实前边的文章中也提到过Context,只不过是 一笔带过,但是宏哥觉得在playwright中挺重要的,所以宏哥今天单独将其拎出来讲解和分享一下,希望对您有所帮助或者参考. 2.前言 Pl ...
- 理解ASP.NET Core - 限流(Rate Limiting)
注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 概述 在微服务化的架构设计中,网关扮演着重要的看门人角色,它所提供的功能之一就是限流.而对于众 ...
- 【go语言】2.3.2 error 接口
在 Go 语言中,error 是一个内置的接口类型,用于表示错误情况.error 接口的定义如下: type error interface { Error() string } 任何具有 Error ...
- 3D相册 复仇者联盟
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- CN2 GIA
搬瓦攻方案库存监控页面 https://stock.bwg.net/ https://bwh81.net/ https://bandwagonhost.com/ https://teddysun.c ...
- CTF中的神兵利刃-foremost工具之文件分离
原理 Foremost可以依据文件内的文件头和文件尾对一个文件进行分离,或者识别当前的文件是什么文件.比如拓展名被删除.被附加也仍然可以对其分离. 使用 安装: 需要使用这个工具,首先我们需要安装他, ...
- [Go笔记] 基础-01: Golang发展简史、著名项目及基本使用
引言 Golang,又称Go语言,是一门开源的静态类型编译型编程语言.自从2007年由谷歌的罗伯特·格里泽默(Robert Griesemer).罗布·派克(Rob Pike)和肯·汤普森(Ken T ...
- 使用kubeadm部署kubernetes
k8s版本:1.15.0 前期准备 节点: master:172.50.13.103(2核2G) node-1:172.50.13.104(2核2G) node-2:172.50.13.105(2核2 ...