C#解決Excel邊框樣式無(wú)法復(fù)制及格式刷功能
問(wèn)題現(xiàn)象
在運(yùn)行數(shù)據(jù)表數(shù)據(jù)導(dǎo)出到 EXCEL 數(shù)據(jù)輸出時(shí)遇到了一個(gè)問(wèn)題,開(kāi)發(fā)者設(shè)計(jì)了單行細(xì)線下邊框的輸出模板,如下圖設(shè)計(jì):
其中 <%system.excel.title.dyna.by.craneoffice%> 字符標(biāo)記用于輸出報(bào)表標(biāo)題替換。數(shù)據(jù)從A5列開(kāi)始至D5列結(jié)束,按行輸出。期望得到如下輸出樣式:
雖然已經(jīng)自定義了復(fù)制樣式的方法,包括邊框風(fēng)格的復(fù)制,但實(shí)際輸出遇到了如下情況:
實(shí)際想要得到的單行細(xì)線下邊框輸出沒(méi)有實(shí)現(xiàn),使用簡(jiǎn)單 Borders.LineStyle 賦值沒(méi)有奏效,以后輸出的行復(fù)制第一行的樣式?jīng)]有成功,因此需要調(diào)整樣式輸出策略,實(shí)現(xiàn)類似格式刷那樣的操作,這樣即實(shí)現(xiàn)了格式輸出的完整性,也保證了性能。
范例運(yùn)行環(huán)境
操作系統(tǒng): Windows Server 2019 DataCenter
.net版本: .netFramework4.0 或以上
Office Excel 2016
開(kāi)發(fā)工具:VS2019 C#
解決方案
剪貼板加特殊粘貼
使用 COM 操作的流程原理如下圖:
實(shí)現(xiàn)代碼,示例如下:
SRange.Copy(); //將源選定范圍復(fù)制到剪貼板 Range.PasteSpecial(Excel.XlPasteType.xlPasteFormats); //特殊粘貼格式到目標(biāo)選定范圍
Copy() 方法實(shí)現(xiàn)了復(fù)制所有數(shù)據(jù)到剪貼板功能,其中也包括了樣式。 PasteSpecial() 方法實(shí)現(xiàn)了指定粘貼的功能,其中 Excel.XlPasteType.xlPasteFormats 表示只粘貼格式樣式,至此實(shí)現(xiàn)了模擬格式刷的功能。 但此方法可能會(huì)引起多 Excel 應(yīng)用的復(fù)制沖突,因此相對(duì)保險(xiǎn)的寫(xiě)法可以改成如下代碼:
SRange.Copy(Range);
但這樣會(huì)有一個(gè)問(wèn)題是,如果像模板輸出還好,但想要僅粘貼格式則無(wú)法實(shí)現(xiàn),因此也有局限性。而且這種實(shí)現(xiàn)原理,微軟可能也會(huì)有所調(diào)整,也無(wú)法保障以后的應(yīng)用是否會(huì)引起復(fù)制沖突。所以我們?cè)谙聜€(gè)小節(jié)通過(guò)自定義樣式的方式來(lái)模擬格式刷的功能。
自定義樣式
使用 COM 操作的流程原理如下圖:
示例代碼如下:
string stylename = Guid.NewGuid().ToString(); WorkBook xb=WorkBooks[1]; Style newStyle = xb.Styles.Add(stylename); 設(shè)置樣式屬性 newStyle.Font.Name = "宋體"; newStyle.Font.Size = 11; newStyle.Font.Bold = true; newStyle.Borders.Weight = XlBorderWeight.xlHairline; //最細(xì)的線 newStyle.Borders.LineStyle = XlLineStyle.xlContinuous; //實(shí)線
以上是添加樣式的示例,因?yàn)闃邮胶芏?,?shí)現(xiàn)格式復(fù)制的簡(jiǎn)單方法,是創(chuàng)建新名稱并直接引用源單元格的樣式,應(yīng)用到目標(biāo)選范圍上即可,如果有需要移除或修改的樣式,可以繼續(xù)對(duì)新建樣式進(jìn)行賦值,修改后如下代碼示例:
string stylename = Guid.NewGuid().ToString(); WorkBook xb=WorkBooks[1]; Style newStyle = xb.Styles.Add(stylename); newStyle = SRange.Style; //將源選定范圍樣式賦值到自定義新建樣式 newStyle.Font.Name="宋體"; //修改字體為宋體 Range.Style = newStyle.Name;
直接賦值
Range.Style 是一個(gè) dynamic 類型,可以賦予任何可以正確實(shí)現(xiàn)的類型,如自定義樣式名稱(newStyle.Name),也可以直接賦值為 Style 類型,簡(jiǎn)單而暴力,代碼如下:
Range.Style = SRange.Style; //將源選定范圍樣式賦值到目標(biāo)
完美方案
在實(shí)際的運(yùn)行中,無(wú)論是自定義樣式還是直接賦值模式,對(duì)復(fù)制字體時(shí)出現(xiàn)了無(wú)法復(fù)制的問(wèn)題,因此還是需要結(jié)合自定義復(fù)制樣式方法來(lái)彌補(bǔ)問(wèn)題,代碼如下:
public void copyRangeStyle(Excel.Range srcRange,Excel.Range desRange) { desRange.Font.Background=srcRange.Font.Background; desRange.Font.Bold=srcRange.Font.Bold; desRange.Font.Color=srcRange.Font.Color; desRange.Font.Italic=srcRange.Font.Italic; desRange.Font.Name=srcRange.Font.Name; desRange.Font.OutlineFont=srcRange.Font.OutlineFont; desRange.Font.Shadow=srcRange.Font.Shadow; desRange.Font.Size=srcRange.Font.Size; desRange.Font.Strikethrough=srcRange.Font.Strikethrough; desRange.Font.Underline=srcRange.Font.Underline; desRange.RowHeight=srcRange.RowHeight; desRange.HorizontalAlignment=srcRange.HorizontalAlignment; desRange.VerticalAlignment=srcRange.VerticalAlignment; }
copyRangeStyle 自定義復(fù)制樣式方法包括 源選定范圍參數(shù)(Excel.Range srcRange)和目標(biāo)選定范圍參數(shù)(Excel.Range desRange),至此,完整代碼可修整如下:
Range.Style = SRange.Style; copyRangeStyle(SRange, Range);
至此結(jié)合 copyRangeStyle 方法完美解決樣式復(fù)制問(wèn)題。
copyRangeStyle 方法請(qǐng)根據(jù)實(shí)際需要的樣式進(jìn)行擴(kuò)充或調(diào)整。
小結(jié)
關(guān)于 Range.Borders 的COM 操作如下圖:
這個(gè)樣式的設(shè)定是有點(diǎn)擊順序的,選邊框后點(diǎn)擊樣式是無(wú)效的,需要點(diǎn)擊樣式再進(jìn)行選邊框的切換,才會(huì)得到預(yù)期效果。正??赏ㄟ^(guò) Range.Borders 直接表示所有6個(gè)框線的集合,直接為其賦值,如下代碼:
newStyle.Borders.Weight = XlBorderWeight.xlHairline; //最細(xì)的線 newStyle.Borders.LineStyle = XlLineStyle.xlContinuous; //實(shí)線類型邊框 newStyle.Borders.Color = Color.Red; //紅色邊框
如果想只設(shè)置某一邊框,則需要獲取 Borders 集合里的 Border,如下幾種方式都可以獲取其中的某一個(gè) Border 對(duì)象:
//右、左、下、上邊框 Range.Borders.get_Item(XlBordersIndex.xlEdgeRight).LineStyle = XlLineStyle.xlLineStyleNone; Range.Borders.get_Item(XlBordersIndex.xlEdgeLeft).LineStyle = XlLineStyle.xlContinuous; Range.Borders.get_Item(XlBordersIndex.xlEdgeBottom).LineStyle = XlLineStyle.xlContinuous; Range.Borders.get_Item(XlBordersIndex.xlEdgeTop).LineStyle = XlLineStyle.xlContinuous; //內(nèi)部交叉斜線 Range.Borders.Item[XlBordersIndex.xlDiagonalDown].LineStyle = XlLineStyle.xlLineStyleNone; Range.Borders[XlBordersIndex.xlDiagonalUp].LineStyle = XlLineStyle.xlLineStyleNone;
我們可以使用 Borders.get_Item 方法或引用 Item 索引或直接引用索引的方法得到 Border,但實(shí)際的使用過(guò)程中,預(yù)期效果不理想,因此我們使用了樣式賦值,類似格式刷的方法來(lái)解決。
以上就是C#解決Excel邊框樣式無(wú)法復(fù)制及格式刷功能的詳細(xì)內(nèi)容,更多關(guān)于C# Excel邊框樣式無(wú)法復(fù)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#巧用DateTime預(yù)設(shè)可選的日期范圍(如本年度、本季度、本月等)
這篇文章主要介紹了C#巧用DateTime預(yù)設(shè)可選的日期范圍,如本年度、本季度、本月等,感興趣的小伙伴們可以參考一下2016-04-04c# 給button添加不規(guī)則的圖片以及用pictureBox替代button響應(yīng)點(diǎn)擊事件的方法
這篇文章介紹了c# 給button添加不規(guī)則的圖片以及用pictureBox替代button響應(yīng)點(diǎn)擊事件的方法,有需要的朋友可以參考一下2013-09-09結(jié)合Visual C#開(kāi)發(fā)環(huán)境講解C#中事件的訂閱和取消訂閱
這篇文章主要介紹了C#中事件的訂閱和取消訂閱,結(jié)合Visual C#開(kāi)發(fā)環(huán)境來(lái)進(jìn)行講解,Visual C#被集成在微軟的IDE程序Visual Studio中,需要的朋友可以參考下2016-01-01C#中泛型舉例List<T>與DataTable相互轉(zhuǎn)換
這篇文章介紹了C#中泛型舉例List<T>與DataTable相互轉(zhuǎn)換的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05C#難點(diǎn)逐個(gè)擊破(8):可空類型System.Nullable
null值用來(lái)表示數(shù)據(jù)類型未被賦予任何值,它是一種引用類型;void表示沒(méi)有類型,或者說(shuō)是沒(méi)有任何值。null與void的區(qū)別可以認(rèn)為void是根本沒(méi)有,而null是一個(gè)空箱子,里面什么都沒(méi)有。2010-02-02C#中使用DataContractSerializer類實(shí)現(xiàn)深拷貝操作示例
這篇文章主要介紹了C#中使用DataContractSerializer類實(shí)現(xiàn)深拷貝操作示例,本文給出了實(shí)現(xiàn)深拷貝方法、測(cè)試深拷貝方法例子、DataContractSerializer類實(shí)現(xiàn)深拷貝的原理等內(nèi)容,需要的朋友可以參考下2015-06-06C#中使用強(qiáng)制類型實(shí)現(xiàn)字符串和ASCII碼之間的轉(zhuǎn)換
這篇文章主要介紹了C#中使用強(qiáng)制類型實(shí)現(xiàn)字符串和ASCII碼之間的轉(zhuǎn)換,本文還給出了另一種方法,需要的朋友可以參考下2014-08-08