選單
GSS 技術部落格
在這個園地裡我們將從技術、專案管理、客戶對談面和大家分享我們多年的經驗,希望大家不管是喜歡或是有意見,都可以回饋給我們,讓我們有機會和大家對話並一起成長!
若有任何問題請來信:gss_crm@gss.com.tw
3 分鐘閱讀時間 (580 個字)

透過 Aspose.Words 讓設定 SectionBreakOddPage(自下個奇數頁起) 的隱藏頁能顯示頁碼

hands-on-the-microsoft-surface-laptop-mockup

問題

最近同事詢問使用 Aspose.Words 是否有 Support ,分隔符號 -> 自下個奇數頁起。
Aspose.Words 可以使用 BreakType.SectionBreakOddPage 。
所以測試程式如下,

var doc = new Aspose.Words.Document();
var builder = new DocumentBuilder(doc);
builder.Writeln("This text is in section 1.");
builder.MoveToHeaderFooter(HeaderFooterType.FooterPrimary);
builder.ParagraphFormat.Alignment = ParagraphAlignment.Center;
builder.InsertField("PAGE", null);
builder.MoveToDocumentEnd();
builder.InsertBreak(BreakType.SectionBreakOddPage);
builder.Writeln("This text is in section 2.");
builder.InsertBreak(BreakType.SectionBreakOddPage);
builder.Writeln("This text is in section 3.");
builder.InsertBreak(BreakType.PageBreak);
builder.Writeln("This text is in section 4.");
doc.Save("sessions.docx");

這樣子的話,如果第一節結束後,Word會替我們補上第2頁的隱藏頁,而這個隱藏頁在 Word 中是看不到的。
只有在列印時,才會顯示出來。如下,

在 Word 中看到的頁數為 1, 3, 5, 6 ,第4個頁碼為6是因為 Section3 之後是使用 BreakType.PageBreak 。

而在列印時, Word 替我們加的第2頁、第4頁,就會顯示出來了,如下,

可以發現,雖然在 Word 中看到的總共有4頁,最後一頁的頁碼為 6 。
列印出來是真的為 6 頁,只是第2頁、第4頁是完全空白的頁面,連頁碼都沒有。
那是否能為那個空白頁加上頁碼(或是讓那個空白頁可以呈現跟其他頁面一樣的 Header 及 Footer)呢?

研究

雖說是Word預設的行為,但是如果沒有頁碼的話,個人是覺得有點奇怪。
想了一下,應該可以將 SectionBreak 換成 PageBreak 這樣子就會顯示出真正的頁面。
所以在建立好資料後,再來個後製處理,將 SectionBreak 換成 PageBreak,如下,


FontSettings.DefaultInstance.SubstitutionSettings.DefaultFontSubstitution.DefaultFontName = "新細明體";
var doc = new Aspose.Words.Document();
var builder = new DocumentBuilder(doc);
builder.Writeln("This text is in section 1.");
builder.MoveToHeaderFooter(HeaderFooterType.FooterPrimary);
builder.ParagraphFormat.Alignment = ParagraphAlignment.Center;
builder.InsertField("PAGE", null);
builder.MoveToDocumentEnd();
builder.InsertBreak(BreakType.SectionBreakOddPage);
builder.Writeln("This text is in section 2.");
builder.InsertBreak(BreakType.SectionBreakOddPage);
builder.Writeln("This text is in section 3.");
builder.InsertBreak(BreakType.PageBreak);
builder.Writeln("This text is in section 4.");
//後製,將 SectionBreak 換成 PageBreak
//讓 空白的頁碼可以出來
var layout = new LayoutCollector(doc);
foreach (var node in doc.ChildNodes)
{
    if (node.NodeType == NodeType.Section)
    {
        var section = (Section)node;
        var sectionStart = section.PageSetup.SectionStart;
        //可以看一下各區段的PageNumber 及 SectionStart
        Console.WriteLine($"Section:{sectionStart}");
        Console.WriteLine($"layout.GetStartPageIndex:{layout.GetStartPageIndex(section)}");
        Console.WriteLine($"layout.GetEndPageIndex:{layout.GetEndPageIndex(section)}");
        Section nextSect = (Section)node.NextSibling;
        if (nextSect != null)
        {
            if (nextSect.PageSetup.SectionStart == SectionStart.OddPage)
            {
                nextSect.PageSetup.SectionStart = SectionStart.NewPage;
                builder.MoveTo(section.Body.LastParagraph);
                //取得區段最後的頁數
                var lastPageNumber = layout.GetEndPageIndex(section);
                //如果是使用 EvenPage 則改用 lastPageNumber % 2 == 0
                if (lastPageNumber % 2 == 1)
                {
                    //如果是單數,表示Word會新增一個分頁,所以補一個分頁給它
                    builder.InsertBreak(BreakType.PageBreak);
                }
            }
        }
    }
}
doc.Save("sessions2.docx");

經過後製處理後,原本的空白頁就產生出來,並且也有頁碼了,如下,


  • 註: 你可能會想說,為什麼不一開始就自已控制去補空白頁呢? 這是因為內容是從資料庫來的,程式不好判斷目前是到第幾頁了,何時要補這個空白頁,所以使用 SectionBreakOddPage or EvenPage 比較方便。
  • 註: 可以從 doc.Count 跟 doc.PageCount 比較,如果 PageCount 比較大則表示 Word 有替我們補隱藏頁
  • 註: 要 Aspose.Words 算出來的頁數正確,文件內容的字型必須為 TrueType
  • 註: 目前在 MAC 環境執行會有頁數不正確的狀況,測試請在 Windows 環境執行

參考資料

How Insert page break?
Aspose.Words Document.Sections Property
Aspose.Words Working with Headers and Footers

Dockeried Service 部署指南
AuthenticationException: Authentication failed, se...

相關文章