1. 程式人生 > >讓我頭疼一下午的Excel合併單元格

讓我頭疼一下午的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表格無法開啟的症狀在網上搜索一通

我將下載的Excel表格的字尾從xlsx改為zip並開啟

開啟sheet1.xml檔案,找到mergeCells標籤,將其內容拷貝到XML線上格式化工具中檢視

經過人眼搜尋,終於發現了問題所在


    ...

    <mergeCell ref="B175:B189"/>

    <mergeCell ref="B176:B190"/>

    ...

這裡顯然出現了覆蓋合併的情況,進而導致開啟Excel報錯的情況(後面經過測試發現,重複合併單元格也會出現同樣的報錯資訊)

順著這個思路,排查程式碼,不斷除錯測試,考慮各種情況下的合併單元格場景,最終搞定了這個稍稍複雜的合併單元格的Excel匯出功能。

一點思考

雖然知道是合併單元格導致的問題,但是在實際調整程式碼時花費了幾乎一個下午,曾經一度頭大到不想思考。

回頭想想,在這個問題上有兩大收穫。

1、排查問題的思路很重要

問題的現象已經擺在眼前,排查了不是非法字元的原因,就應該尋找其他原因

利用一切可以利用的手頭資訊比如上面簡短而關鍵的報錯日誌資訊。

活用搜索引擎,這種問題肯定已經有前人踩過雷,去看下他們是怎麼排雷的就好,不用自己再去研究排雷的具體方法了。

2、寫程式碼之前先想好

現在想想這段合併單元格的程式碼是不是可以寫的更加漂亮,我想應該是可以的,但是能不能從30行精簡為10行甚至5行,我想這不太可能。

因為這個匯出合併時會遇到各種情況,比如連續相同的單元格何時合併,空白行如何保證不合並,某空白行區域前和後又如何實現合併等問題。

所以,寫這段程式碼前應該先梳理所有可能的場景包括一些特殊情況,盡其所能羅列所有的情況,這樣才能保證在應對各種情形的資料時正常匯出。

程式碼稍後我會放到專案rome裡

對了,匯出效果圖呈上

如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的“推薦”將是我最大的寫作動力!如果您想持續關注我的文章,請掃描二維碼,關注JackieZheng的微信公眾號,我會將我的文章推送給您,並和您一起分享我日常閱讀過的優質文章。