NPOI處理Word文本中段落編號


NPOI的XWPFParagraph對象中,是無法直接讀取段落編號的,然而可以讀取的是編號的樣式名稱(GetNumFmt),編號分組ID(GetNumID),編號樣式(NumLevelText)等。具體如下:

/*
             * 若干格式信息
             * GetNumFmt: decimal, GetNumID: 1, GetNumIlvl: 0, NumLevelText: %1. => 1.
             * GetNumFmt: decimal, GetNumID: 4, GetNumIlvl: 0, NumLevelText: %1) => 1)
             * GetNumFmt: chineseCountingThousand, GetNumID: 2, GetNumIlvl: 0, NumLevelText: (%1) => (一)
             * GetNumFmt: chineseCountingThousand, GetNumID: 3, GetNumIlvl: 0, NumLevelText: %1、 => 一、
             * GetNumFmt: upperLetter, GetNumID: 5, GetNumIlvl: 0, NumLevelText: %1. => A.
             * GetNumFmt: decimal, GetNumID: 6, GetNumIlvl: 0, NumLevelText: %1、 => 1、
             */
若干格式信息

於是封裝了段落編號的處理類,幾個關鍵點:

1、考慮頻繁調用,使用單例。

2、依照NumLevelText內容替換編號的樣式

3、編號分組發生變化時,編號要重置為1,采用字典記錄

4、漢字、字母統一處理為數字編號

5、讀取一個新Word時,字典內容要清空

段落處理類:

 1     /// <summary>
 2     /// 段落處理類
 3     /// Author: Matsuyoi
 4     /// </summary>
 5     class ParagraphNumHandle
 6     {
 7         #region 封裝為單例
 8         private static ParagraphNumHandle singleton = null;
 9         public static ParagraphNumHandle GetInstance()
10         {
11             if (singleton == null)
12                 singleton = new ParagraphNumHandle();
13             //獲取單例后重置一次變量
14             singleton.Reset();
15             return singleton;
16         }
17         #endregion
18         //Num字典
19         private Dictionary<string, int> _Count;
20         private ParagraphNumHandle()
21         {
22             _Count = new Dictionary<string, int>();
23         }
24         /// <summary>
25         /// 重置
26         /// </summary>
27         private void Reset()
28         {
29             //清空字典
30             _Count.Clear();
31         }
32         /// <summary>
33         /// 處理段落中的編號,漢字與字母編號統一轉為數字編號
34         /// </summary>
35         /// <param name="paragraph"></param>
36         /// <returns></returns>
37         public string GetParagraphNum(XWPFParagraph paragraph)
38         {
39             string result = "";
40             //若無編號格式信息,則返回空
41             if (string.IsNullOrEmpty(paragraph.GetNumFmt()) ||
42                 string.IsNullOrEmpty(paragraph.GetNumID()) ||
43                 string.IsNullOrEmpty(paragraph.NumLevelText))
44             {
45                 return result;
46             }
47 
48             string key = paragraph.GetNumID() ?? "";
49             if (!_Count.ContainsKey(key))
50             {
51                 //編號從1開始
52                 _Count.Add(key, 1);
53             }
54             else
55             {
56                 _Count[key] += 1;
57             }
58 
59             string fmt = paragraph.NumLevelText.Replace("%1", "{0}");
60             result = string.Format(fmt, _Count[key].ToString()) + " ";
61             return result;
62         }
63     }

調用方式:

//段落編號處理
ParagraphNumHandle pnc = ParagraphNumHandle.GetInstance(); //正文段落
foreach (XWPFParagraph paragraph in document.Paragraphs)
{
//獲取段樓中的編號
string num = pnc.GetParagraphNum(paragraph);

...

}

延續上一篇《NPOI處理Word文本中上下角標》的示例,完整代碼如下:

/// <summary>
        /// 讀取Word,並識別文本中的上下角標
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static string ReadWordTextExWithSubscript(string fileName)
        {

            string fileText = string.Empty;
            StringBuilder sbFileText = new StringBuilder();

            #region 打開文檔
            XWPFDocument document = null;
            try
            {
                using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                {
                    document = new XWPFDocument(file);
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            #endregion
            //段落編號處理
            ParagraphNumHandle pnc = ParagraphNumHandle.GetInstance();
            //正文段落
            foreach (XWPFParagraph paragraph in document.Paragraphs)
            {
                //獲取段樓中的句列表
                IList<XWPFRun> runsLists = paragraph.Runs;
                //獲取段樓中的編號
                string num = pnc.GetParagraphNum(paragraph);
                sbFileText.Append("<p>" + num);
                foreach (XWPFRun run in runsLists)
                {
                    switch (run.Subscript)
                    {
                        case VerticalAlign.BASELINE:
                            sbFileText.Append(run.Text);
                            break;
                        //上角標
                        case VerticalAlign.SUPERSCRIPT:
                            sbFileText.Append("<sup>" + run.Text + "</sup>");
                            break;
                        //下角標
                        case VerticalAlign.SUBSCRIPT:
                            sbFileText.Append("<sub>" + run.Text + "</sub>");
                            break;
                        default:
                            sbFileText.Append(run.Text);
                            break;
                    }
                   
                }
                sbFileText.AppendLine("</p>");
            }
            fileText = sbFileText.ToString();

            return fileText;
        }
View Code

 

測試:

Word文檔:

輸出:

<p>1. 第一段</p>
<p>2. 第二段</p>
<p>1) 第三段</p>
<p>(1) 第四段</p>
<p>(2) 第五段</p>
<p>1、 第六段</p>
<p>2、 第七段</p>
<p>1. 第八段</p>
<p>1、 第九段</p>
<p>2、 第十段</p>
<p>測試<sup>上</sup><sub>下</sub>ok。</p>
<p>CO<sub>2</sub></p>
<p>面積約6000km<sup>2</sup></p>

Html預覽:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM