Excel导出常见问题

excel导出其实不算什么难事

在网上copy下模板代码,填充自己的业务数据,提供一个http接口基本就可以得到你要导出的数据了。

但是,凡事都有例外,截止今天,excel导出我遇到的主要是两大类问题

1、大数据量的excel数据,比如几十万条甚至更多的数据导出

2、因为excel中内容的问题,导致导出后的excel不能直接打开,报错“由于一些内容不可取,Excel无法打开xxx.xlsx。是否要打开并修复此工作簿?”

针对第一种大数据量问题,我遇到的主要问题是excel存储的记录上限和导出超时等问题

解决方法是将导出格式为xls升级为xlsx,xls每个sheet最多支持65536条记录,xlsx最多支持1048576条记录;超时则可以采用前端直接返回,后端异步取数据并导出的方式避免超时。

这种情况不是今天要介绍的重点,今天要介绍的第二种情况的解决思路。

需求描述

1、层级关系最多为四级

2、对于相同层级,如果内容相同需要纵向合并单元格,空白行不需要合并

3、样例数据如下所示


一级目录1,二级目录1,三级目录1,四级目录2, 一级目录1,二级目录1,三级目录3, 一级目录1,二级目录1,三级目录5, 一级目录1,二级目录3, 一级目录1,二级目录5,三级目录5, 一级目录2,二级目录2,三级目录2, 一级目录2,二级目录2,三级目录3, 一级目录2,二级目录4,三级目录4, 一级目录2,二级目录7, 一级目录3,二级目录6,三级目录4, 一级目录3,二级目录6,三级目录10, 一级目录4, 一级目录5,二级目录8,三级目录6,

解决思路

将上面样例数据存入一个集合中,遍历每条记录并存放到相应的单元格。

如果不需要合并单元格,到这里,就可以提供导出的Excel了。

但是重点是合并单元格。

遇到的问题

初步排查

自认为代码已经就位,调用接口,Excel文件也成功下载了,结果打开的那一刻一个对话框让我头疼了一下午。

报错信息如下

第一反应是肯定数据错乱了,估计是单元格之间相互挤占,数据肯定也是不堪入目。

但是我按照智能的Excel提示,点击“打开并修复”后发现,数据没有我想的那么糟,甚至仔细看看,发现居然没有问题。

有点小激动的同时,心里还是有点不爽,总不能让别人每次导出的时候都使用这个智能的“打开并修复”功能才能看导出的数据吧。

但是光从这个报错信息来看确实没有什么线索,于是网上找了一通与“由于一些内容不可取,Excel无法打开xxx.xlsx。是否要打开并修复此工作簿?”有关的解决方法。虽然有不少人遇到过这样的问题,但是引起问题的原因不太一样,有些是因为sheet的命名包含特殊字符,有些是导出的Excel内容中有非法字符,还有说要在response的header中加入Content-length字段的。

进一步排查

搜了一通,没有什么进展,这时候想起来在刚刚点击“打开并修复”后,还弹出了一个对话框,于是点击对话框中的查看

得到线索如下


<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><logFileName>修复结果到 xxx.xml</logFileName><summary>在文件“/Users/jackie/Downloads/xxx.xlsx”中检测到错误</summary><removedRecords summary="以下是已删除记录的列表:"><removedRecord>已删除的记录: /xl/worksheets/sheet1.xml 的 合并单元格</removedRecord></removedRecords></recoveryLog>

排除了前面提到的种种非法字符的原因,看到线索里的“合并单元格”,基本可以断定这是因为在合并单元格的过程中出了问题。

寻找问题根本原因

结合合并单元格导致Excel表格无法打开的症状在网上搜索一通

http://www.360doc.com/content/14/0107/11/14931240_343269914.shtml这篇文章给出了解决思路

我将下载的Excel表格的后缀从xlsx改为zip并打开

打开sheet1.xml文件,找到mergeCells标签,将其内容拷贝到XML在线格式化工具中查看

经过人眼搜索,终于发现了问题所在


... <mergeCell ref="B175:B189"/> <mergeCell ref="B176:B190"/> ...

这里显然出现了覆盖合并的情况,进而导致打开Excel报错的情况(后面经过测试发现,重复合并单元格也会出现同样的报错信息)

顺着这个思路,排查代码,不断调试测试,考虑各种情况下的合并单元格场景,最终搞定了这个稍稍复杂的合并单元格的Excel导出功能。

一点思考

虽然知道是合并单元格导致的问题,但是在实际调整代码时花费了几乎一个下午,曾经一度头大到不想思考。

回头想想,在这个问题上有两大收获。

1、排查问题的思路很重要

问题的现象已经摆在眼前,排查了不是非法字符的原因,就应该寻找其他原因

利用一切可以利用的手头信息比如上面简短而关键的报错日志信息。

活用搜索引擎,这种问题肯定已经有前人踩过雷,去看下他们是怎么排雷的就好,不用自己再去研究排雷的具体方法了。

2、写代码之前先想好

现在想想这段合并单元格的代码是不是可以写的更加漂亮,我想应该是可以的,但是能不能从30行精简为10行甚至5行,我想这不太可能。

因为这个导出合并时会遇到各种情况,比如连续相同的单元格何时合并,空白行如何保证不合并,某空白行区域前和后又如何实现合并等问题。

所以,写这段代码前应该先梳理所有可能的场景包括一些特殊情况,尽其所能罗列所有的情况,这样才能保证在应对各种情形的数据时正常导出。

代码稍后我会放到项目rome里

项目地址:https://github.com/DMinerJackie/rome

对了,导出效果图呈上

如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!如果您想持续关注我的文章,请扫描二维码,关注JackieZheng的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。

让我头疼一下午的Excel合并单元格的更多相关文章

  1. asp.net C#取Excel 合并单元格内容

    asp教程.net c#取excel 合并单元格内容读取excel数据,填充dataset// 连接字符串 string xlspath = server.mappath("~/www.11 ...

  2. NPOI之Excel——合并单元格、设置样式、输入公式

    首先建立一个空白的工作簿用作测试,并在其中建立空白工作表,在表中建立空白行,在行中建立单元格,并填入内容: //建立空白工作簿 IWorkbook workbook = new HSSFWorkboo ...

  3. 【NetOffice Excel】Excel合并单元格【原】

    CSharp操作Excel采用开源的原生.NET程序集NetOffice,格式兼容性更好. 在操作Excel的时候有时候需要合并单元格 using ExcelOffice = NetOffice.Ex ...

  4. NPOI之Excel——合并单元格、设置样式、输入公式、设置筛选等

    首先建立一个空白的工作簿用作测试,并在其中建立空白工作表,在表中建立空白行,在行中建立单元格,并填入内容: //建立空白工作簿 IWorkbook workbook = new HSSFWorkboo ...

  5. poi excel 合并单元格

    结论:final CellRangeAddress cra = new CellRangeAddress(rowId, rowId + rowSkip,        colId, colId + c ...

  6. poi导出excel合并单元格(包括列合并、行合并)

    1 工程所需jar包如下:commons-codec-1.5.jarcommons-logging-1.1.jarlog4j-1.2.13.jarjunit-3.8.1.jarpoi-3.9-2012 ...

  7. 创建excel,合并单元格,设置单元格样式

    package com.huawei.excel; import java.io.File;import java.io.FileOutputStream;import java.util.Date; ...

  8. excel 合并 单元格内容

    刚刚有人问怎么合并单元格内容,正好excel 我也不会,顺便查查记录一下 1.假设有两个单元格如下:           单元格1 单元格2           2. 在一个空白单元格输入 =( 这代 ...

  9. [办公应用]如何将excel合并单元格分拆后每个单元格上仍保留数据?

    合并单元格虽然美观,但是无法进行排序.筛选等操作. 只有合并单元格拆分后才可以按常规进行统计.但是普通拆分后,excel仅保留合并单元格数据到区域左上角的单元格. 解决方案:选定多个合并单元格,应用本 ...

随机推荐

  1. P3353 在你窗外闪耀的星星

    飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀着你玫瑰色的脸颊.我明 ...

  2. Intellij IDEA 解决 Maven 依赖下载慢的问题

    最近用 IDEA 导入 Hadoop 源码, 但下载依赖特别慢.导致经常需要重启 IDEA 并且下载的过程非常艰难, 网上找了一些方法,各种尝试,终于解决了这个问题.本篇文章总结最关键的两点,希望能帮 ...

  3. webstorm离线装载Material Theme UI

    首先说说需求,由于直接用webstorm听说VS挺火的,但是初恋的感觉是其他任何编辑器无法替代的 瞎说了一些话,新公司内网开发,用的是vscode,但是我还是喜欢用webstorm,连不上网,所以不能 ...

  4. asp.net core 依赖注入实现全过程粗略剖析(2)

    接着 上篇 目前也算是交代清楚了相关的类.那么框架具体是如何来实例化的呢?整个的流程是怎么样的. 我们参考源码中的Test文件夹来看看: var collection = new ServiceCol ...

  5. React性能优化记录(不定期更新)

    React性能优化记录(不定期更新) 1. 使用PureComponent代替Component 在新建组件的时候需要继承Component会用到以下代码 import React,{Componen ...

  6. 网络测试工具 - QCheck

    本片博客内容借鉴51CTO中joyssue博主文章. 网络性能不仅与交换和路由设备的性能相关,而且与线路质量也有很大关系.使用Qcheck可以测试网络性能.这是NetIQ公司开发的一款免费网络测试软件 ...

  7. BZOJ4267 : 小强的颜色

    首先剔除$1$号心情不能到达的无用心情,然后采用分割法进行DFA的最小化. 每次遍历所有集合,将集合中和集合中第一个心情行为或者转移所在集合不同的心情放入新集合中. 最后按字典序依次给每个集合编号即可 ...

  8. Yii2 数组助手类arrayHelper

    数组助手类 ArrayHelper 1.什么是数组助手类 Yii 数组助手类提供了额外的静态方法,让你更高效的处理数组. a.获取值(getValue) class User { public $na ...

  9. Python实现图像信息隐藏

    Python实现图像信息隐藏 之前学习密码学的时候老师有提到过『信息隐藏』,现在用图像的方法尝试一下.思想是:把信息藏到RGB通道中的B通道,然后利用奇偶性可以恢复过来 原理 从源图中提取文字图像信息 ...

  10. Spring Boot使用Druid连接池基本配置

    以下为Spring Boot配置Druid 一.pom.xml配置 <dependency> <groupId>com.alibaba</groupId> < ...