1+ namespace MiniSoftware . Extensions
2+ {
3+ using DocumentFormat . OpenXml . Wordprocessing ;
4+ using System ;
5+ using System . Collections ;
6+ using System . Collections . Generic ;
7+ using System . ComponentModel ;
8+ using System . Dynamic ;
9+ using System . Linq ;
10+ using System . Text ;
11+
12+ internal static class OpenXmlExtension
13+ {
14+ /// <summary>
15+ /// 高级搜索:得到段落里面的连续字符串
16+ /// </summary>
17+ /// <param name="paragraph">段落</param>
18+ /// <returns>Item1:连续文本;Item2:块;Item3:块文本</returns>
19+ internal static List < Tuple < string , List < Run > , List < Text > > > GetContinuousString ( this Paragraph paragraph )
20+ {
21+ List < Tuple < string , List < Run > , List < Text > > > tuples = new List < Tuple < string , List < Run > , List < Text > > > ( ) ;
22+ if ( paragraph == null )
23+ return tuples ;
24+
25+ var sb = new StringBuilder ( ) ;
26+ var runs = new List < Run > ( ) ;
27+ var texts = new List < Text > ( ) ;
28+
29+ //段落:所有子级
30+ foreach ( var pChildElement in paragraph . ChildElements )
31+ {
32+ //块
33+ if ( pChildElement is Run run )
34+ {
35+ //文本块
36+ if ( run . IsText ( ) )
37+ {
38+ var text = run . GetFirstChild < Text > ( ) ;
39+ runs . Add ( run ) ;
40+ texts . Add ( text ) ;
41+ sb . Append ( text . Text ) ;
42+ }
43+ else
44+ {
45+ if ( runs . Any ( ) )
46+ tuples . Add ( new Tuple < string , List < Run > , List < Text > > ( sb . ToString ( ) , runs , texts ) ) ;
47+
48+ sb = new StringBuilder ( ) ;
49+ runs = new List < Run > ( ) ;
50+ texts = new List < Text > ( ) ;
51+ }
52+ }
53+ //公式,书签...
54+ else
55+ {
56+ //跳过的类型
57+ if ( pChildElement is BookmarkStart || pChildElement is BookmarkEnd )
58+ {
59+
60+ }
61+ else
62+ {
63+ if ( runs . Any ( ) )
64+ tuples . Add ( new Tuple < string , List < Run > , List < Text > > ( sb . ToString ( ) , runs , texts ) ) ;
65+
66+ sb = new StringBuilder ( ) ;
67+ runs = new List < Run > ( ) ;
68+ texts = new List < Text > ( ) ;
69+ }
70+ }
71+ }
72+
73+ if ( runs . Any ( ) )
74+ tuples . Add ( new Tuple < string , List < Run > , List < Text > > ( sb . ToString ( ) , runs , texts ) ) ;
75+
76+ sb = null ;
77+ runs = null ;
78+ texts = null ;
79+
80+ return tuples ;
81+ }
82+
83+ /// <summary>
84+ /// 整理字符串到连续字符串块中
85+ /// </summary>
86+ /// <param name="texts">连续字符串块</param>
87+ /// <param name="text">待整理字符串</param>
88+ internal static void TrimStringToInContinuousString ( this IEnumerable < Text > texts , string text )
89+ {
90+ /*
91+ //假如块为:[A][BC][DE][FG][H]
92+ //假如替换:[AB][E][GH]
93+ //优化块为:[AB][C][DE][FGH][]
94+ */
95+
96+ var allTxtx = string . Concat ( texts . SelectMany ( o => o . Text ) ) ;
97+ var indexState = allTxtx . IndexOf ( text ) ;
98+ if ( indexState == - 1 )
99+ return ;
100+
101+ int indexEnd = indexState + text . Length - 1 ;
102+ List < Tuple < int , char > > yl = new List < Tuple < int , char > > ( allTxtx . Length ) ;
103+ int iRun = 0 ;
104+ int iIndex = 0 ;
105+ int iRunOf = - 1 ;
106+ foreach ( var item in texts )
107+ {
108+ foreach ( var item2 in item . Text )
109+ {
110+ if ( indexState <= iIndex && iIndex <= indexEnd )
111+ {
112+ if ( iRunOf == - 1 )
113+ iRunOf = iRun ;
114+
115+ yl . Add ( new Tuple < int , char > ( iRunOf , item2 ) ) ;
116+ }
117+ else
118+ {
119+ yl . Add ( new Tuple < int , char > ( iRun , item2 ) ) ;
120+ }
121+
122+ iIndex ++ ;
123+ }
124+ iRun ++ ;
125+ }
126+
127+ int i = 0 ;
128+ foreach ( var item in texts )
129+ {
130+ item . Text = string . Concat ( yl . Where ( o => o . Item1 == i ) . Select ( o => o . Item2 ) ) ;
131+ i ++ ;
132+ }
133+
134+ }
135+
136+
137+ internal static bool IsText ( this Run run )
138+ {
139+ return run . Elements ( ) . All ( o => o is Text || o is RunProperties ) ;
140+ }
141+ }
142+ }
0 commit comments