[Office | Word | C#] Word浮水印系列(3)-判斷是否有不正確的浮水印圖片或遺漏Section未被插入圖片-檢查Section與Link To Previous與紙張大小,方向等狀況。

在前一篇[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手動插入圖片的範例:

LinkToPrevious 對不同Section插入圖片的影響

 

你會發現,如果下一個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加入浮水印。

插入浮水印(Watermark)圖片至不同紙張大小(PageSize)的Section

 

 

後記

 


 

一開始做Word的浮水印圖片插入時,覺得很容易,但是做下去後,才發現其實問題比想像中多,所以也才會產生這些系列,這些是我所遇到的一些經驗,透過這些文章也分享給各位。

 


 

文章中的敘述如有觀念不正確錯誤的部分,歡迎告知指正 謝謝 =)

另外要轉載請附上出處 感謝