iT邦幫忙

1

[開發經驗分享][.NET C#]如何在Excel表單加入浮水印

前言

在之前的文章當中有提到過,如何將Excel匯出為PDF,且不使用 Microsoft Office的套件,經過好多曲折離奇的嘗試之後,終於達成需求,不過這回客戶又有新的需求了,那就是要在Excel以及PDF上加入浮水印,但是因為Excel畢竟不是真正的報表軟體,它是其實是試算表(但很多客戶喜歡把它當報表來用,我也不知道為什麼),所以並沒有真正意義上的浮水印功能,所以我把方向稍稍改變,變成是在Excel背景加入淡化的圖片,同樣能達成浮水印的目標,以下是我所嘗試的解決方法,開始囉。

正解(?):在頁首頁尾插入圖片

由於是Excel,加上原本電腦就有安裝 Microsoft Office,已經用習慣了,所以很理所當然地先用Microsoft Excel打開xlsx檔案,先看要怎麼從MS Excel加入浮水印。

同樣,有問題就先找Google大師,在搜尋了Excel 浮水印這個簡單的關鍵字後,發現官方有提供解法,但官方也講得很明白,Excel並沒有提供浮水印的功能,不過可以用在頁首頁尾加入圖片來實現浮水印的功能,看來官方也了解到會有這種(特異的)需求,還開了一頁做說明:D

官方文章:在 Excel 中新增浮水印

按照步驟設定完之後,在編輯畫面上,並不會出現圖片,如下。

https://ithelp.ithome.com.tw/upload/images/20200203/201162044QnZiBu1rO.jpg

這是因為,頁首頁尾只會在列印的時候被列印出來,所以如果改成預覽列印,就會出現所設定的圖片。

https://ithelp.ithome.com.tw/upload/images/20200203/20116204ci2FrIrKRl.jpg

實驗成功後,接下來就是把這個步驟設定頁首→中間插入圖片,轉換成程式碼,EPPLUS套件要插入頁首圖片的程式碼也相當簡單。

//偶數頁設定頁首圖片
sheet.HeaderFooter.EvenHeader.InsertPicture(new
    FileInfo(HttpContext.Current.Server.MapPath("~/Content/images/excelbk.png")),
    PictureAlignment.Centered);
//奇數頁設定頁首圖片
sheet.HeaderFooter.OddHeader.InsertPicture(new
    FileInfo(HttpContext.Current.Server.MapPath("~/Content/images/excelbk.png")),
    PictureAlignment.Centered);

打完收工,一切是這麼的順利且完美。

事情沒有這麼順利

正當我興高采烈的執行測試,產生Excel之後,打開卻赫然發現圖片不見了,這是發生甚麼事了??

其實線索十分明確,聰明(?)的我,也不會忘記,產生Excel檔案用的並不是MS Excel的套件,而是使用LibreOffice的sdk,所以就朝這方向去找問題,馬上將有圖片的那個Excel檔案用LibreOffice打開看看,也不會出現圖片,那就不是C#程式碼的問題了。

下圖,一樣的檔案,左邊用MS Excel打開會有圖片,右邊用LibreOffice打開就沒有圖片。

https://ithelp.ithome.com.tw/upload/images/20200203/20116204UG0MCOmJ4o.jpg

於是乎,試著用LibreOffice來插入頁首的圖片看看,結果發現,LibreOffice並沒有可以在頁首插入圖片的功能,頁首頁尾設定的項目,由左至右分別是:

  • 文字特性
  • 標題、檔案名稱、路徑/檔案名稱
  • 工作表名稱
  • 頁碼
  • 總頁數
  • 日期
  • 時間
    並沒有一個選項可以選擇插入圖片,也因為這樣,所以在頁首頁尾插入圖片當作浮水印,結論是GG

https://ithelp.ithome.com.tw/upload/images/20200203/20116204eAMbtSXZFi.jpg

替代方案:背景圖片

正規(?)的方法不行,那就只好想替代方案了,那就是一開始所想到的,給它一個背景圖就好,沒有採用是因為,背景圖只會出現一遍,不能適用於有分頁的報表,而頁首頁尾可以自動在每頁都加上圖片,比較方便,所以就先試頁首頁尾,現在既然頁首頁尾不行,那就變回插入背景圖,然後在計算它每一頁大約的資料量,就可以在每一頁都出現這個背景圖,也就達成浮水印的功能了。

//6是表頭的資料行數
//30是每頁會出現的資料行數
//這兩個數字請自行判斷
for (var i = 6; i <= data.Data.Count; i += 30)
{
    //圖片路徑
    var img = sheet.Drawings.AddPicture($"bkImage{i}",
        new FileInfo(HttpContext.Current.Server.MapPath("~/Content/images/excelbk.png")));
    //圖片位置依序為:行、RowOffsetPixel、列、ColumnOffsetPixel
    //RowOffsetPixel與ColumnOffsetPixel可以不用設定
    img.SetPosition(i, 0, 2, 0);
}

修改後結果顯示如下,左邊是MS Excel編輯畫面,右邊是LibreOffice編輯畫面,使用這種方法,在編輯畫面也看得到圖片,當然列印也可以。

https://ithelp.ithome.com.tw/upload/images/20200203/201162040O5V7rjIpi.jpg

總結

用插入圖片這種替代方案,固然是可以解決需求,不過缺點是,編輯畫面可以隨意拖拉圖片,不過這也是無可奈何的解法,畢竟Excel本來就沒有浮水印的功能,如果也有夥伴們遇到需要在Excel上加入浮水印的需求的話,然後又有買MS Office授權,就直接用MS Excel插入頁首頁尾吧!但如果只能用免費的OpenOffice來做的話,這邊提供一個替代的解決方案,以上謝謝各位收看。


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
yuwen
iT邦新手 4 級 ‧ 2020-02-04 09:23:25

請教一下,為何開發時要採用LibreOffice的sdk,而不採用MSOffice的sdk?因為從文章的描述來看,似乎是SDK不支援造成無法插入浮水印。小弟沒有相關經驗,純粹只是好奇。

看更多先前的回應...收起先前的回應...
威廉蕭 iT邦新手 5 級 ‧ 2020-02-04 10:32:16 檢舉

因為客戶(尤其是政府單位)沒有買MS Office授權,而使用MS Office的sdk需要安裝MS Office,沒有安裝就沒辦法使用,所以就只能用不用錢的LibreOffice的sdk,加上政府單位也主要推行OpenOffice,所以只好捨棄好用的MS Office。

yuwen iT邦新手 4 級 ‧ 2020-02-07 08:43:01 檢舉

原來是有這樣的限制,但這樣聽起來似乎用ClosedXML之類的套件大概也無法解決吧

威廉蕭 iT邦新手 5 級 ‧ 2020-02-07 16:36:15 檢舉

您是指ClosedXml?
ClosedXml與Epplus是一樣用來產出Excel的,如果要把Excel匯出成Pdf還是得用OpenOffice或MS Office或者購買第三方套件。

yuwen iT邦新手 4 級 ‧ 2020-02-10 09:33:35 檢舉

原來如此(筆記筆記),感謝告知

我要留言

立即登入留言