当前位置: 首页 > news >正文

使用Freemarker模版导出xls文件使用excel打开提示文件损坏

本文是通过一步步的还原事件的发生并解决的一个过程记录,如果想知道如何解决的可以直接跳转文章末尾结论部分

提示一下,关注一下 Table 标签中的 ss:ExpandedRowCount 属性

解决的问题

在项目中使用freemarker的xml模板导出xls格式的Excel文件时,使用国产Office工具可以打开查看,使用Excel打开提示文件已损坏

关键词

国产office,Excel,freemarker

环境信息

  • Windows 11
  • office 2019
  • 永中office2022体验版
  • JDK8
  • springboot 2.6.13
  • freemarker 2.6.13

事件还原

1、首先使用Excel创建一个空白excel文件,输入我们要导出的表格模板,如下图所示,我们创建一个表格,表格中导出姓名、年龄、电话、住址等信息的这样一个表格,并且添加了一行示例数据

alt

2、点击另存为,选中xml格式导出

alt

3、打开xml文件,修改添加数据的地方,使用freemarker语法遍历输出数据

修改前如下图所示

alt

修改后如下图所示

alt

其中的#list为固定语法,resultList为获取输入模板数据的key,该值是一个Listas item是*List**中的每一个对象以item来遍历

item.name为获取姓名,item.age为获取年龄,item.phont为获取电话,item.address为获取住址

${item.name!''}的完整意思就是输出用户名,为空时输出为空

4、创建springboot程序,并在resources下创建freemarker目录,继续创建test.xml模板文件,test.xml文件内容就是上一步我们修改完成之后的xml文件,结构如下

alt

文件内容如下(本内容为Excel打开异常的,如需正常的,需跳转文章末尾

提示一下,关注一下 Table 标签中的 ss:ExpandedRowCount 属性

<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"xmlns:o="urn:schemas-microsoft-com:office:office"xmlns:x="urn:schemas-microsoft-com:office:excel"xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"xmlns:html="http://www.w3.org/TR/REC-html40"><DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>zuiyu</Author><LastAuthor>zuiyu</LastAuthor><Created>2023-07-26T02:16:31Z</Created><LastSaved>2023-07-26T02:18:00Z</LastSaved><Version>16.00</Version></DocumentProperties><OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office"><AllowPNG/></OfficeDocumentSettings><ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel"><WindowHeight>5880</WindowHeight><WindowWidth>14400</WindowWidth><WindowTopX>32767</WindowTopX><WindowTopY>32767</WindowTopY><ProtectStructure>False</ProtectStructure><ProtectWindows>False</ProtectWindows></ExcelWorkbook><Styles><Style ss:ID="Default" ss:Name="Normal"><Alignment ss:Vertical="Center"/><Borders/><Font ss:FontName="等线" x:CharSet="134" ss:Size="11" ss:Color="#000000"/><Interior/><NumberFormat/><Protection/></Style></Styles><Worksheet ss:Name="Sheet1"><Table ss:ExpandedColumnCount="4" ss:ExpandedRowCount="2" x:FullColumns="1"x:FullRows="1" ss:DefaultColumnWidth="51" ss:DefaultRowHeight="13.875"><Row><Cell><Data ss:Type="String">姓名</Data></Cell><Cell><Data ss:Type="String">年龄</Data></Cell><Cell><Data ss:Type="String">电话</Data></Cell><Cell><Data ss:Type="String">住址</Data></Cell></Row><#list resultList as item><Row><Cell><Data ss:Type="String">${item.name!''}</Data></Cell><Cell><Data ss:Type="Number">${item.age!''}</Data></Cell><Cell><Data ss:Type="Number">${item.phone!''}</Data></Cell><Cell><Data ss:Type="String">${item.address!''}</Data></Cell></Row></#list></Table><WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"><PageSetup><Header x:Margin="0.3"/><Footer x:Margin="0.3"/><PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/></PageSetup><Selected/><Panes><Pane><Number>3</Number><ActiveRow>4</ActiveRow><ActiveCol>5</ActiveCol></Pane></Panes><ProtectObjects>False</ProtectObjects><ProtectScenarios>False</ProtectScenarios></WorksheetOptions>
</Worksheet></Workbook>

5、编写导出excel文件的代码,都是测试数据,看看就好,只是举个例子

需要关注的点是,我们此处导出的用户数据为100,而上文中提示需要关注的参数ss:ExpandedRowCount参数值为2,这就是后文要探讨的关键所在

package com.example.exceldemo.demos.excel;import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URLEncoder;
import java.util.*;/*** @Author zuiyu* @Date 2023/7/26 10:26*/
@RestController
@RequestMapping("/excel")
public class ExcelController {@GetMapping("/export")public void export(HttpServletResponse response) throws IOException, TemplateException {Configuration configuration = new Configuration(Configuration.VERSION_2_3_26);configuration.setDefaultEncoding("utf-8");configuration.setClassForTemplateLoading(getClass(),"/freemarker");Template template = configuration.getTemplate("test.xml");List<Person> list = new ArrayList<>();for (int i = 0; i < 100; i++) {Person person1 = new Person();person1.setName("测试用户名:"+i);person1.setAge((i+1)*2);person1.setPhone(new Random().nextInt(100));person1.setAddress("地址:"+i);list.add(person1);}Map<String,Object> map = new HashMap<>();map.put("resultList",list);ServletOutputStream outputStream = response.getOutputStream();response.setContentType("application/octet-stream");response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("测试xml导出excel.xls", "UTF-8"));BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));template.process(map,bw);bw.flush();bw.close();System.out.println("导出成功");}
}

6、下面执行接口http://localhost:8080/excel/export导出xls文件进行查看文件内容,我们的预期就是国产Office可以打开观看,而Excel打开时提示文件已损坏。打开结果就不进行展示了,感兴趣的可以使用上面的代码进行一下测试

7、下面我们修改ss:ExpandedRowCount="2"ss:ExpandedRowCount="9999",这样就可以容纳我们的100条记录。此时重启程序进行导出我们就可以发现不管是使用Excel查看还是国产Office查看都可以进行正常的显示了

8、下面是修改之后的完整的xml文件内容

<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"xmlns:o="urn:schemas-microsoft-com:office:office"xmlns:x="urn:schemas-microsoft-com:office:excel"xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"xmlns:html="http://www.w3.org/TR/REC-html40"><DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>zuiyu</Author><LastAuthor>zuiyu</LastAuthor><Created>2023-07-26T02:16:31Z</Created><LastSaved>2023-07-26T02:18:00Z</LastSaved><Version>16.00</Version></DocumentProperties><OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office"><AllowPNG/></OfficeDocumentSettings><ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel"><WindowHeight>5880</WindowHeight><WindowWidth>14400</WindowWidth><WindowTopX>32767</WindowTopX><WindowTopY>32767</WindowTopY><ProtectStructure>False</ProtectStructure><ProtectWindows>False</ProtectWindows></ExcelWorkbook><Styles><Style ss:ID="Default" ss:Name="Normal"><Alignment ss:Vertical="Center"/><Borders/><Font ss:FontName="等线" x:CharSet="134" ss:Size="11" ss:Color="#000000"/><Interior/><NumberFormat/><Protection/></Style></Styles><Worksheet ss:Name="Sheet1"><Table ss:ExpandedColumnCount="4" ss:ExpandedRowCount="9999" x:FullColumns="1"x:FullRows="1" ss:DefaultColumnWidth="51" ss:DefaultRowHeight="13.875"><Row><Cell><Data ss:Type="String">姓名</Data></Cell><Cell><Data ss:Type="String">年龄</Data></Cell><Cell><Data ss:Type="String">电话</Data></Cell><Cell><Data ss:Type="String">住址</Data></Cell></Row><#list resultList as item><Row><Cell><Data ss:Type="String">${item.name!''}</Data></Cell><Cell><Data ss:Type="Number">${item.age!''}</Data></Cell><Cell><Data ss:Type="Number">${item.phone!''}</Data></Cell><Cell><Data ss:Type="String">${item.address!''}</Data></Cell></Row></#list></Table><WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"><PageSetup><Header x:Margin="0.3"/><Footer x:Margin="0.3"/><PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/></PageSetup><Selected/><Panes><Pane><Number>3</Number><ActiveRow>4</ActiveRow><ActiveCol>5</ActiveCol></Pane></Panes><ProtectObjects>False</ProtectObjects><ProtectScenarios>False</ProtectScenarios></WorksheetOptions>
</Worksheet></Workbook>

总结

通过这次实验可以得知,文件的打开失败的根本原因就是数据行超过了设置的ExpandedRowCount属性值。而我们要做的就是修改该值到能容纳我们要导出的数据即可。甚至是可以改为变量读取数据长度是否可行 。

如果感觉有用的话欢迎点赞、收藏、转发,关注公众号《醉鱼Java》获取一手面试资料,一起学编程

本文由 mdnice 多平台发布

相关文章:

使用Freemarker模版导出xls文件使用excel打开提示文件损坏

本文是通过一步步的还原事件的发生并解决的一个过程记录&#xff0c;如果想知道如何解决的可以直接跳转文章末尾结论部分 提示一下&#xff0c;关注一下 Table 标签中的 ss:ExpandedRowCount 属性 解决的问题 在项目中使用freemarker的xml模板导出xls格式的Excel文件时&#xf…...

初识Linux

今天简单了解了关于操作系统的发展史&#xff0c;学习了在Linux中如何远程连接云服务器的指令&#xff0c;以及在Linux中创建多个用户的指令。 1. ssh root 服务器远程地址 作用是用来连接XShell与云服务器&#xff0c;输入该指令后会自动生成输入密码的窗口&#xff0c;如…...

python——案例六:清空列表用clear()方法实现

案例六&#xff1a;清空列表用clear()方法实现LIST[0,1,2,3,4,5] print(清空前&#xff1a;,LIST) LIST.clear() print(清空后&#xff1a;,LIST)...

测试|Selenium之WebDriver常见API使用

测试|Selenium之WebDriver常见API使用 文章目录 测试|Selenium之WebDriver常见API使用1.定位对象&#xff08;findElement&#xff09;css定位xpath定位css选择器语法&#xff1a;xpath语法:校验结果 2.操作对象鼠标点击对象在对象上模拟按键输入clear清除对象输入的文本内容su…...

手把手教你uniapp和小程序分包

分包目的在于提高小程序的体积&#xff0c;多一个包就多2M&#xff0c;最多20M 常规的分包&#xff1a; 小程序一打开首先加载主包&#xff0c;然后再加载分包 分包可以用主包内的资源&#xff0c;主包不可以使用分包的资源 分包A不可以使用分包B里面的内容 分包可以使用a…...

Java中的代理模式

Java中的代理模式 1. 静态代理2. JDK动态代理3. CGLib动态代理 1. 静态代理 接口 public interface ICeo {void meeting(String name) throws InterruptedException; }目标类 public class Ceo implements ICeo{public void meeting(String name) throws InterruptedExcepti…...

LeetCode每日一题——1331.数组序号转换

题目传送门 题目描述 给你一个整数数组 arr &#xff0c;请你将数组中的每个元素替换为它们排序后的序号。 序号代表了一个元素有多大。序号编号的规则如下&#xff1a; 序号从 1 开始编号。一个元素越大&#xff0c;那么序号越大。如果两个元素相等&#xff0c;那么它们的…...

2、Tomcat介绍(下)

组件分类 在Apache Tomcat中&#xff0c;有几个顶级组件&#xff0c;它们是Tomcat的核心组件&#xff0c;负责整个服务器的运行和管理。这些顶级组件包括&#xff1a; Server(服务器)&#xff1a;Tomcat的server.xml配置文件中的<Server>元素代表整个Tomcat服务器实例。每…...

JAVA 正则表达式(heima)

JAVA 正则表达式&#xff08;heima&#xff09; public class RegexDemo01 {/** 正则表达式介绍&#xff1a;本质来说就是一个字符串&#xff0c;字符串中可以指定规则&#xff0c;来对其他字符串进行校验。* public boolean matches(String regex):根据传入的正则表达式&#…...

布瑞特单圈绝对值旋转编码器串口数据读取

布瑞特单圈绝对值旋转编码器串口数据读取 数据手册&#xff1a;http://briter.net/col.jsp?id109 (2.1版本RS485说明书通信协议 单圈.pdf) 绝对式编码器为布瑞特BRT38-ROM16384-RT1&#xff0c;采用RS485通信。 该绝对式编码器共有5根线&#xff1a;红、黄、黑、绿、白 由…...

Linux第六章之vim与gcc使用

一、Linux编辑器-vim使用 vi/vim的区别简单点来说&#xff0c;它们都是多模式编辑器&#xff0c;不同的是vim是vi的升级版本&#xff0c;它不仅兼容vi的所有指令&#xff0c;而且还有一些新的特性在里面。例如语法加亮&#xff0c;可视化操作不仅可以在终端运行&#xff0c;也…...

【Golang】Golang进阶系列教程--为什么说 Go 语言字符串是不可变的?

文章目录 前言推荐阅读 前言 最近有读者留言说&#xff0c;平时在写代码的过程中&#xff0c;是会对字符串进行修改的&#xff0c;但网上都说 Go 语言字符串是不可变的&#xff0c;这是为什么呢&#xff1f; 这个问题本身并不困难&#xff0c;但对于新手来说确实容易产生困惑…...

ES开启身份认证

文章目录 X-Pack简介之前的安全方案ES开启认证ES服务升级https协议开启集群节点之间的证书认证 X-Pack简介 X-Pack是Elastic Stack扩展功能&#xff0c;提供安全性&#xff0c;警报&#xff0c;监视&#xff0c;报告&#xff0c;机器学习和许多其他功能。 X-Pack的发展演变&am…...

Docker安装es以及ik分词器

1、拉取镜像 docker pull elasticsearch:7.10.12、下载对应版本的ik分词、并将它们解压到ik文件夹下&#xff0c;如图 https://github.com/medcl/elasticsearch-analysis-ik/releases 3、在服务器上创建文件夹 mkdir /usr/elklog/elk/es mkdir /usr/elklog/elk/es/data mkdi…...

中断、进程调度、进程切换、系统调用,模式切换的那些事情

提示&#xff1a;风萧声动&#xff0c;玉壶光转&#xff0c;一夜鱼龙舞 文章目录 前言中断进程调度进程切换线程切换模式切换所以他们有什么关系&#xff1f; 前言 本文内容主要参考以下几个博文中学得 进程与线程&#xff08;中&#xff09;的2.2.7 进程切换VS模式切换&#…...

使用web-view实现网页端和uni-app端是数据传输

要实现这个功能 第一步&#xff1a;要在vue的public文件夹下面引入 <script type"text/javascript" src"https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script> 第二步&#xff1a;建立一个新的空的uni-app项目…...

Ajax快速入门

Ajax Ajax就是前端访问服务器端数据的一个技术 还有主要就是异步交互 就是在不刷新整页面的情况下&#xff0c;和服务器交换部分我也数据 比如搜索的联想技术 同步和异步的概念 一个是客户端需要等待服务器完成处理&#xff0c;才能进行别的事 一个是客户端不需要等待服务器处…...

Google OAuth 2 authorization - Error: redirect_uri_mismatch 400

出现这个问题&#xff0c;一般是因为google授权origin地址和重定向redirect_uri地址没有匹配上。 请仔细检查重定向地址的url中origin部分和授权origin部分是否能够匹配&#xff1a;...

Qt 中操作xml文件和JSON字符串

文章目录 1、概述1.1、xml介绍1.2、json介绍 2、xml文件增删改查2.1、写xml文件内容2.2、读xml文件内容2.3、删除xml文件内容2.4、修改xml文件内容 3、构建JSON字符串3.1、JSON字符串排版4、剪切板操作 1、概述 1.1、xml介绍 XML 指可扩展标记语言&#xff08;EXtensible Mark…...

React 基础篇(二)

&#x1f4bb; React 基础篇&#xff08;二&#xff09;&#x1f3e0;专栏&#xff1a;React &#x1f440;个人主页&#xff1a;繁星学编程&#x1f341; &#x1f9d1;个人简介&#xff1a;一个不断提高自我的平凡人&#x1f680; &#x1f50a;分享方向&#xff1a;目前主攻…...

突破性创新:Midscene.js如何用AI视觉驱动重塑跨平台自动化测试

突破性创新&#xff1a;Midscene.js如何用AI视觉驱动重塑跨平台自动化测试 【免费下载链接】midscene AI-powered, vision-driven UI automation for every platform. 项目地址: https://gitcode.com/GitHub_Trending/mid/midscene 在当今复杂的软件生态中&#xff0c;跨…...

LaserGRBL:5分钟掌握开源激光雕刻控制软件的核心功能

LaserGRBL&#xff1a;5分钟掌握开源激光雕刻控制软件的核心功能 【免费下载链接】LaserGRBL Laser optimized GUI for GRBL 项目地址: https://gitcode.com/gh_mirrors/la/LaserGRBL LaserGRBL是一款专为GRBL控制器优化的开源激光雕刻控制软件&#xff0c;为Windows用户…...

别再对着示波器数NOP了!用STM32的SPI+DMA驱动WS2812灯带,一个CubeMX配置就搞定

用STM32的SPIDMA高效驱动WS2812灯带&#xff1a;告别手动调时序的工程化方案 在嵌入式开发中&#xff0c;驱动WS2812灯带一直是个让人又爱又恨的挑战。这种智能RGB灯带以其简单的单线控制和丰富的色彩表现广受欢迎&#xff0c;但精确的时序要求也让不少开发者头疼不已。传统方法…...

环境配置与基础教程:保姆级教程:在 Mac M 芯片上利用 MPS 加速 YOLO 训练与推理的完整环境搭建

写在前面:为什么你的 Mac 也能跑深度学习? 几年前,如果有人告诉你用 MacBook 训练深度学习模型,你大概会笑出声。那时候 Mac 上的 PyTorch 只能依赖 CPU 吭哧吭哧地算,训练一个小模型都要等到天荒地老。但自从 Apple Silicon 芯片(M1、M2、M3、M4,以及最新的 M5)横空出…...

Arm架构在中国市场的机遇、挑战与实战指南

1. 项目概述&#xff1a;Arm架构的“中国故事”与我的观察最近几年&#xff0c;在技术圈和投资圈里&#xff0c;“Arm架构”和“中国市场”这两个词的组合热度一直居高不下。作为一名长期关注处理器架构和产业生态的从业者&#xff0c;我几乎每周都能在行业交流、客户会议甚至供…...

PlayAI多语种翻译能力边界实测(含方言识别、专业术语库热加载、混合语种断句逻辑),你敢信它已通过ISO/IEC 24615标准认证?

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;PlayAI多语种同步翻译功能详解 PlayAI 的多语种同步翻译功能基于端到端神经机器翻译&#xff08;NMT&#xff09;架构与实时语音流处理引擎深度融合&#xff0c;支持中、英、日、韩、法、西、德、俄等 …...

PYTHON基础入门----商品库存管理系统

如果商品信息只保存在程序运行过程中&#xff0c;那么程序关闭后&#xff0c;所有数据都会丢失。因此&#xff0c;我们需要将商品数据保存到文件中&#xff0c;下次运行程序时还能继续读取和使用。本题要求你编写一个简单的商品库存管理系统&#xff0c;实现商品的添加、查看、…...

ZoneMinder开源监控系统:30分钟打造专业级安防解决方案,支持IP/USB/模拟摄像头全兼容

ZoneMinder开源监控系统&#xff1a;30分钟打造专业级安防解决方案&#xff0c;支持IP/USB/模拟摄像头全兼容 【免费下载链接】zoneminder ZoneMinder is a free, open source Closed-circuit television software application developed for Linux which supports IP, USB and…...

从零搭建CFD-DEM耦合环境:OpenFOAM与PFC3D在WSL2下的实战部署指南

1. 环境准备&#xff1a;WSL2与Ubuntu基础配置 第一次接触CFD-DEM耦合仿真的同学&#xff0c;建议从Windows系统起步。微软的WSL2&#xff08;Windows Subsystem for Linux&#xff09;现在已经能完美支持Ubuntu环境&#xff0c;实测比虚拟机流畅得多。我去年在联想小新Pro16上…...

Nintendo Switch大气层破解系统终极指南:从入门到精通完整教程

Nintendo Switch大气层破解系统终极指南&#xff1a;从入门到精通完整教程 【免费下载链接】Atmosphere-stable 大气层整合包系统稳定版 项目地址: https://gitcode.com/gh_mirrors/at/Atmosphere-stable 大气层整合包系统是为Nintendo Switch设备提供的一站式定制化固件…...