在前一篇[Office | Word |C#]Word浮水印系列(2)-判斷頁首頁尾類型與插入圖片至奇偶頁(OddEvenPageHeaderFooter)與第一頁頁首頁尾(FirstPageHeaderFooter) 針對的是一個Section內的頁首頁尾類型狀況,接下來要開始考慮不同Section之間彼此的影響,為何說會有影響,因為Section每一節,都會在版面配置時,有一個功能叫做「連結至前一節」(Link To Previous) ,此功能會使一些「插入」的物件有複製的效果,以下來介紹,與處理的方式。
前言
在前一篇[Office | Word |C#]Word浮水印系列(2)-判斷頁首頁尾類型與插入圖片至奇偶頁(OddEvenPageHeaderFooter)與第一頁頁首頁尾(FirstPageHeaderFooter) 針對的是一個Section內的頁首頁尾類型狀況,接下來要開始考慮不同Section之間彼此的影響,為何說會有影響?
因為Section每一節,都會在版面配置時,有一個功能叫做「連結至前一節」(Link To Previous) ,此功能會使一些「插入」的物件有複製的效果,以下來介紹,與處理的方式。
「連結至前一節」(Link To Previous) 對Sections的影響
前言提到,Section每一節,都會在版面配置時,有一個功能叫做「連結至前一節」(Link To Previous) ,此功能會使一些「插入」的物件有複製的效果。
而插入圖片即是非常明顯的例子,只要一插入,即便是不同的Section,都會插入此圖片,如下是我開啟Word手動插入圖片的範例:
你會發現,如果下一個Section有設定 Link To Previous ,並且 紙張的大小或方向與前一個我現在插入圖片所指定的Section不同,則會變得很突兀,如果內文是個大表格,就會無法全部蓋到,因此我們應該多考慮一些狀況。
考慮目前Section是否為LinkToPrevious與紙張大小與方向
因此,由於作業的程序,是先對First Section 去做浮水印的頁首頁尾設定,所以第一個Section不需考慮其他的複雜狀況,只需知道此插入的Section是什麼紙張大小與判斷頁首頁尾類習作插入。
再來,開始對後續的Section處理,此時才需考慮狀況:
1. 考慮目前的Section是否有設定LinkToPrevious,如果沒有,則一開始的First Section插入浮水印圖片便不會因為LinkToPrevious的效果被複製到,所以我們在對此Section做浮水印圖片插入。
2. 若是此Section有設定LinkToPrevious ,則我們還須判斷,如果此Section與前一個Section是不同的紙張方向 或是 不同的紙張大小,那麼此浮水印圖片便對目前的Section不適合。我們便需要把因為LinkToPrevious的關係複製到的不適當的浮水印圖片,刪除!並從新製作適合此Section的圖片,並且刪除後,不能夠把LinkToPrevious變回True,否則Word又會再次把前一個Section的圖片貼到我們現在處理好的Section!
如下是程式碼區塊的介紹:
首先如上所述,先對第一個Section做處理。
//浮水印要透過Section的頁首頁尾插入,而每一個Section可能包含了許多頁(非頁碼的頁數),所以一旦插入浮水印至此Section,同一個Section的頁面都會插入
//另外,同一個Section,紙張大小與方向都會一致,所以無須擔心其中某一頁方向或大小不同
//若是方向或大小不同,則代表了那是另一個Section
//需要考量的是PrevoiusToLink造成的影響,PrevoiusToLink是Link到前一個Section,不同紙張大小的Section因為PrevoiusToLink,有了不適合的浮水印圖片
Word.WdPaperSize prevSectionPageSize = sections.First.PageSetup.PaperSize;
Word.WdOrientation preSectionOrienation = sections.First.PageSetup.Orientation;
//1. 先對First Section做設定,如果預設文件有LinkToPrevious則會全部插入同張大小浮水印圖片
//此部分插入第一個Section,請至系列2的文章觀看
再來,統一的做法便是先判斷若此Section有設定LinkToPrevious ,且此Section與前一個Section是不同的紙張方向 或是 不同的紙張大小 把LinkToPrevious 改成False,然後再統一處理LinkToPrevious 為False的Section插入圖片。
for (int section_index = 2; section_index < sections.Count + 1; section_index++)
{
Word.Section currentSection = sections[section_index];
//2.1 產生符合目前Section適合的浮水印圖片大小
//浮水印Code ..
//2.2 如果Section的PaperSize不同或是頁面的方向不同,則需要重新設定這個Section用的浮水印
//如果有方向有變,文件PaperSize的寬高也會自動更換,所以不需要再做寬高的互換
CheckSectionPaperSizeAndOrientaionAndChangedLinkToPrevious(ref prevSectionPageSize, ref preSectionOrienation, currentSection);
//2.3 檢查是否有Section頁面是頁首頁尾沒有設定LinkToPrevious
// 若有沒設定,代表一開始插入浮水印的圖片不會在此Section也加入,則需要補插入浮水印。
// 或是因為先前版面大小與方向不一致,於先前所做的插入浮水印動作時會使LinkToPrevious設為false,導致這邊可能會再加入一次
// 因此統一都先清除原先的圖片,再加入
CheckNonPreviousToLinkSectionsAndAddNewWatermark(sections, /*浮水印]圖片的檔案路徑*/, currentSection);
}
以上是大方向的流程面,而實作檢查Section的方向與紙張大小部分如下:
需要對Section的每一個頁首頁尾類型都做檢查。
/// <summary>
/// 檢查是否有Section的紙張大小與方向與前一張不同,但表需要替換屬於此Section的浮水印
/// </summary>
/// <param name="prevSectionPageSize">前一頁的紙張大小</param>
/// <param name="preSectionOrienation">前一頁的紙張方向</param>
/// <param name="currentSection">現在的Section</param>
private static void CheckSectionPaperSizeAndOrientaionAndChangeLinkToPrevious(ref Word.WdPaperSize prevSectionPageSize, ref Word.WdOrientation preSectionOrienation, Word.Section currentSection)
{
if (prevSectionPageSize != currentSection.PageSetup.PaperSize || preSectionOrienation != currentSection.PageSetup.Orientation)
{
//先把LinkToPrevious設為false,以避免插入新的適合浮水印圖片後,會因此LinkToPrevious導致其他原先正確的Section又被插入依次浮水印圖片
currentSection.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].LinkToPrevious = false;
if (currentSection.PageSetup.DifferentFirstPageHeaderFooter == WORD_TRUE)
currentSection.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterFirstPage].LinkToPrevious = false;
if (currentSection.PageSetup.OddAndEvenPagesHeaderFooter == WORD_TRUE)
currentSection.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterEvenPages].LinkToPrevious = false;
//紀錄現在的方向與紙張大小,作為下次的Section比較的依據
preSectionOrienation = currentSection.PageSetup.Orientation;
prevSectionPageSize = currentSection.PageSetup.PaperSize;
}
}
重新插入浮水印的部分如下:
/// <summary>
/// 檢查是否有Section頁面是頁首頁尾沒有設定LinkToPrevious
/// 若有沒設定,代表一開始插入浮水印的圖片不會在此Section也加入,則需要補插入浮水印。
/// 但是會有例外是因為版面大小與方向不依,於先前所做的插入浮水印動作時會使LinkToPrevious設為false,導致這邊可能會再加入一次
/// 因此統一都先清除原先的圖片,再加入。
/// </summary>
/// <param name="sections">用來操作Application物件所需要</param>
/// <param name="wordTextWmFullPathName">浮水印圖片檔案所在的路徑名稱</param>
/// <param name="currentSection">現在的Section</param>
private void CheckNonPreviousToLinkSectionsAndAddNewWatermark(Word.Sections sections, string wordTextWmFullPathName, Word.Section currentSection)
{
//判別有沒有LinkToPrevious,有就跳過,沒有則進入
//判斷是對三種Index做設定
if (currentSection.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].LinkToPrevious == false)
{
Word.WdHeaderFooterIndex wdHeaderFooterType = Word.WdHeaderFooterIndex.wdHeaderFooterPrimary;
//因為版面大小與方向不依,於先前所做的插入浮水印動作時會使LinkToPrevious設為false,導致這邊可能會再加入一次
//因此統一都先清除原先的圖片,再加入。
DeletePreviousUncorrectWmAndAddNewer(sections, wordTextWmFullPathName, currentSection, wdHeaderFooterType);
}
//判斷有無Section是屬於第一頁首頁尾的狀況,並且沒有PreviousToLink
if (currentSection.PageSetup.DifferentFirstPageHeaderFooter == WORD_TRUE && currentSection.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterFirstPage].LinkToPrevious == false)
{
Word.WdHeaderFooterIndex wdHeaderFooterType = Word.WdHeaderFooterIndex.wdHeaderFooterFirstPage;
DeletePreviousUncorrectWmAndAddNewer(sections, wordTextWmFullPathName, currentSection, wdHeaderFooterType);
}
//判斷有無Section是屬於奇偶首頁尾的狀況,並且偶數頁沒有PreviousToLink(奇數頁預設是一般頁首頁尾,所以在一開始就有先插入)
if (currentSection.PageSetup.OddAndEvenPagesHeaderFooter == WORD_TRUE && currentSection.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterEvenPages].LinkToPrevious == false)
{
Word.WdHeaderFooterIndex wdHeaderFooterType = Word.WdHeaderFooterIndex.wdHeaderFooterEvenPages;
DeletePreviousUncorrectWmAndAddNewer(sections, wordTextWmFullPathName, currentSection, wdHeaderFooterType);
}
}
最後刪除原先浮水印圖片並插入新的圖片的程式:
/// <summary>
/// 刪除原先可能插入錯誤的浮水印圖片,並新增適合的浮水印圖片
/// </summary>
/// <param name="sections"></param>
/// <param name="wordTextWmFullPathName"></param>
/// <param name="currentSection"></param>
/// <param name="wdHeaderFooterType"></param>
private void DeletePreviousUncorrectWmAndAddNewer(Word.Sections sections, string wordTextWmFullPathName, Word.Section currentSection, Word.WdHeaderFooterIndex wdHeaderFooterType)
{
//透過模擬選擇點選Shape來移除才可成功
//點選當前Section的wdSeekCurrentPageHeader,選取此HeaderFooter下範圍的物件,用應用程式的Selection指令刪除(註:刪除指令如果沒有先設定SeekView會失敗,因為沒有點選頁首頁尾所以模擬上會失敗)
sections.Application.ActiveWindow.ActivePane.View.SeekView = Word.WdSeekView.wdSeekCurrentPageHeader;
currentSection.Headers[wdHeaderFooterType].Range.Select();
sections.Application.Selection.Delete();
//插入新的圖片至頁首頁尾
AddWatermarkToPageHeaderFooter(currentSection.Headers[wdHeaderFooterType], wordTextWmFullPathName, (int)currentSection.PageSetup.PageWidth, (int)currentSection.PageSetup.PageHeight);
}
如此便可以處理一份不同紙張大小與方向的Word加入浮水印。
後記
一開始做Word的浮水印圖片插入時,覺得很容易,但是做下去後,才發現其實問題比想像中多,所以也才會產生這些系列,這些是我所遇到的一些經驗,透過這些文章也分享給各位。
文章中的敘述如有觀念不正確錯誤的部分,歡迎告知指正 謝謝 =)
另外要轉載請附上出處 感謝