关于通过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(); } }
浙公网安备 33010602011771号