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 . InnerText ) ;
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 = new StringBuilder ( ) ;
77+ runs = new List < Run > ( ) ;
78+ texts = new List < Text > ( ) ;
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 index = string . Concat ( texts . SelectMany ( o => o . Text ) ) . IndexOf ( text ) ;
97+ if ( index > 0 )
98+ {
99+ int i = - 1 ;
100+ int addLengg = 0 ;
101+ bool isbr = false ;
102+ foreach ( var textWord in texts )
103+ {
104+ if ( addLengg > 0 )
105+ {
106+ isbr = true ;
107+ var leng = textWord . Text . Length ;
108+
109+ if ( addLengg - leng > 0 )
110+ {
111+ addLengg -= leng ;
112+ textWord . Text = "" ;
113+ }
114+ else if ( addLengg - leng == 0 )
115+ {
116+ textWord . Text = "" ;
117+ break ;
118+ }
119+ else
120+ {
121+ textWord . Text = textWord . Text . Substring ( addLengg ) ;
122+ }
123+ }
124+ else if ( isbr )
125+ {
126+ break ;
127+ }
128+ else
129+ {
130+ i += textWord . Text . Length ;
131+ //开始包含
132+ if ( i >= index )
133+ {
134+ //全部包含
135+ if ( textWord . Text . Contains ( text ) )
136+ {
137+ break ;
138+ }
139+ //部分包含
140+ else
141+ {
142+ var str1 = textWord . Text . Substring ( 0 , i - index + 1 ) ;
143+ if ( i == index )
144+ str1 = "" ;
145+
146+ var str2 = str1 + text ;
147+
148+ addLengg = str2 . Length - textWord . Text . Length ;
149+ textWord . Text = str2 ;
150+ }
151+ }
152+ }
153+ }
154+ }
155+ }
156+
157+
158+ internal static bool IsText ( this Run run )
159+ {
160+ return run . Elements ( ) . All ( o => o is Text || o is RunProperties ) ;
161+ }
162+ }
163+ }
0 commit comments