使用C#解決Excel自動(dòng)適應(yīng)列寬的問題
問題現(xiàn)象
通過 COM 操作 Excel 自動(dòng)適應(yīng)列寬的方法是 AutoFit 方法,該方法適于自動(dòng)適應(yīng)列寬或行高。
最近在我們的一款應(yīng)用里發(fā)現(xiàn)效果并沒有符合預(yù)期,我們提供了一個(gè)可以設(shè)置導(dǎo)出Excel花名冊(cè)的配置功能,如下圖:
通過查詢配置表,可以看到當(dāng)選擇需要輸出的列的時(shí)候,可以設(shè)置 excel 列的寬度,以滿足輸出樣式。列寬的值可以設(shè)置0到255的數(shù)值,在 C# 中列寬(ColumnWidth)是一個(gè) dynamic 類型,如下示例代碼:
Range _range=excel.Range[excel.Cells[1,1],excel.Cells[65536,1]]; _range.ColumnWidth=255;
通過獲取 Range 對(duì)象,將其 ColumnWidth 設(shè)置為我們配置的值。在我們的應(yīng)用里,如果配置為 -1 ,則表示使用自動(dòng)適應(yīng)列寬模式,這就用到了如下代碼:
Range _range=excel.Range[excel.Cells[1,1],excel.Cells[65536,1]]; if(config_width==-1){ _range.Columns.AutoFit(); }
我們?cè)趹?yīng)用里配置了類似“家庭成員情況”、“主要社會(huì)關(guān)系人” 、“學(xué)習(xí)經(jīng)歷”、“工作經(jīng)歷” 等履歷型的多行文本輸出,使用了自動(dòng)適應(yīng)列寬模式,輸出效果如下:
實(shí)際上是我們想要得到這樣的效果:
原因分析
根據(jù)輸出效果,我們?cè)?Excel 里模擬操作一下自適應(yīng)列寬,將鼠標(biāo)移動(dòng)到指定的列的表頭的分隔線處,鼠標(biāo)形狀會(huì)顯示為左右箭頭分隔狀,然后雙擊即可實(shí)現(xiàn)自動(dòng)列寬。
發(fā)現(xiàn)有以下幾種情況:
(1)如果單元格未設(shè)置為自動(dòng)換行,我們將列寬手動(dòng)調(diào)小于文字顯示的長度,雙擊后將成功自動(dòng)適應(yīng)為最大文字長度的合適列寬。
(2)如果單元格設(shè)置為自動(dòng)換行,我們將列寬手動(dòng)調(diào)小于文字顯示的長度,雙擊后將沒有達(dá)成預(yù)期的顯示列寬。
(3)如果單元格設(shè)置為自動(dòng)換行,我們將列寬手動(dòng)調(diào)大于多行文字顯示的長度,雙擊后將成功自動(dòng)適應(yīng)為最大文字長度的合適列寬。
因此我們可以使用 C# 模擬情況(3)的操作來解決情況(2)的問題。
范例運(yùn)行環(huán)境
操作系統(tǒng): Windows Server 2019 DataCenter
.net版本: .netFramework4.0 或以上
Office Excel 2016
開發(fā)工具:VS2019 C#
解決問題
生成測試文本
我們假設(shè)生成了如下 HtmlTable 表格內(nèi)容:
姓名 | 與本人關(guān)系 | 政治面目 | 工作單位 | 職務(wù) |
姓名1 | 父親 | 群眾 | 工作單位工作單位 | 工人 |
姓名2 | 母親 | 群眾 | 工作單位2 | 員工 |
姓名3 | 子女 | 群眾 | 無工作單位 | 無 |
我們通過遍歷行列的方法,計(jì)算每個(gè)單元格相對(duì)于列的最大字節(jié)數(shù) GetByteCount(不是長度Length),示例代碼如下:
for (int i = 0; i < mtable.Rows[0].Cells.Count; i++) { int maxlen = 0; for (int j = 0; j < mtable.Rows.Count; j++) { HtmlTableCell curcell=mtable.Rows[j].Cells[i]; int curlen=System.Text.Encoding.Default.GetByteCount(curcell.InnerText); if (curlen > maxlen) { maxlen = curlen; } } mtable.Rows[0].Cells[i].Attributes["maxlen"] = maxlen.ToString(); } string excel = ""; for (int i = 0; i < mtable.Rows.Count; i++) { for (int j = 0; j < mtable.Rows[i].Cells.Count; j++) { int maxlen =int.Parse(mtable.Rows[0].Cells[j].Attributes["maxlen"]); HtmlTableCell curcell = mtable.Rows[i].Cells[j]; excel += curcell.InnerText + string.Concat(Enumerable.Repeat(" ", maxlen - System.Text.Encoding.Default.GetByteCount(curcell.InnerText)))+" " ; curcell.InnerText); } excel += "\r\n"; }
實(shí)現(xiàn)自適應(yīng)
通過生成測試文本,保存到數(shù)據(jù)庫并輸出到 Excel 指定列,實(shí)現(xiàn)自適應(yīng)非常簡單,將列值設(shè)置為最大值,再使用自適應(yīng)AutoFit 方法,即可以讓 Excel 自動(dòng)計(jì)算并重新調(diào)整列寬,代碼如下:
Range _range=excel.Range[excel.Cells[1,1],excel.Cells[65536,1]]; if(config_width==-1){ _range.ColumnWidth = 255; _range.Columns.AutoFit(); }
自此完美解決。
小結(jié)
到此這篇關(guān)于使用C#解決Excel自動(dòng)適應(yīng)列寬的問題的文章就介紹到這了,更多相關(guān)C# Excel自適應(yīng)列寬內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C# List<T> Contains<T>()的用法小結(jié)
本篇文章主要是對(duì)C#中List<T> Contains<T>()的用法進(jìn)行了總結(jié)介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2014-01-01C#使用動(dòng)態(tài)規(guī)劃解決0-1背包問題實(shí)例分析
這篇文章主要介紹了C#使用動(dòng)態(tài)規(guī)劃解決0-1背包問題,實(shí)例分析了C#動(dòng)態(tài)規(guī)劃算法的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04C#實(shí)現(xiàn)軟件開機(jī)自啟動(dòng)的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)軟件開機(jī)自啟動(dòng),且不需要管理員權(quán)限,文中的示例代碼講解詳細(xì),需要的小伙伴可以參考一下2023-07-07Unity實(shí)現(xiàn)游戲傷害數(shù)字顯示HUD的方法
游戲中收到傷害掉血,會(huì)有飄動(dòng)的傷害數(shù)值,本文主要介紹Unity實(shí)現(xiàn)游戲傷害數(shù)字顯示HUD的方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10簡單對(duì)比C#程序中的單線程與多線程設(shè)計(jì)
這篇文章主要介紹了C#程序中的單線程與多線程設(shè)計(jì)的簡單對(duì)比,通過實(shí)際的代碼演示可以清晰看出多線程并發(fā)來避免單線程阻塞問題的特點(diǎn),需要的朋友可以參考下2016-04-04C#使用ThreadPriority設(shè)置線程優(yōu)先級(jí)
這篇文章介紹了C#使用ThreadPriority設(shè)置線程優(yōu)先級(jí)的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04