讓我頭疼一下午的Excel合並單元格


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的微信公眾號,我會將我的文章推送給您,並和您一起分享我日常閱讀過的優質文章。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM