zhao
2021-06-04 c7ec496f9e41c2227103b3ef776e4a3f91bce6b2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
/* ====================================================================
   Licensed to the Apache SoftwAre Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at
 
       http://www.apache.org/licenses/LICENSE-2.0
 
   Unless required by applicable law or agreed to in writing, softwAre
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */
 
namespace HH.WMS.Utils.NPOI.HSSF.UserModel
{
    using System;
    using System.Collections;
    using System.Text.RegularExpressions;
    using System.Text;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
 
    /// <summary>
    /// Common class for HSSFHeader and HSSFFooter
    /// </summary>
    public abstract class HeaderFooter:HH.WMS.Utils.NPOI.SS.UserModel.IHeaderFooter
    {
        protected bool stripFields = false;
 
        /**
         * @return the internal text representation (combining center, left and right parts).
         * Possibly empty string if no header or footer is set.  Never <c>null</c>.
         */
        public abstract String RawText { get; }
        
        private String[] SplitParts()
        {
            String text = RawText;
            // default values
            String _left = "";
            String _center = "";
            String _right = "";
 
            while (text.Length > 1)
            {
                if (text[0] != '&') 
                {
                        _center = text;
                        break;
                }
                int pos = text.Length;
                switch (text[1])
                {
                    case 'L':
                        if (text.IndexOf("&C", StringComparison.Ordinal) >= 0)
                        {
                            pos = Math.Min(pos, text.IndexOf("&C", StringComparison.Ordinal));
                        }
                        if (text.IndexOf("&R", StringComparison.Ordinal) >= 0)
                        {
                            pos = Math.Min(pos, text.IndexOf("&R", StringComparison.Ordinal));
                        }
                        _left = text.Substring(2, pos - 2);
                        text = text.Substring(pos);
                        break;
                    case 'C':
                        if (text.IndexOf("&L", StringComparison.Ordinal) >= 0)
                        {
                            pos = Math.Min(pos, text.IndexOf("&L", StringComparison.Ordinal));
                        }
                        if (text.IndexOf("&R", StringComparison.Ordinal) >= 0)
                        {
                            pos = Math.Min(pos, text.IndexOf("&R", StringComparison.Ordinal));
                        }
                        _center = text.Substring(2, pos - 2);
                        text = text.Substring(pos);
                        break;
                    case 'R':
                        if (text.IndexOf("&C", StringComparison.Ordinal) >= 0)
                        {
                            pos = Math.Min(pos, text.IndexOf("&C", StringComparison.Ordinal));
                        }
                        if (text.IndexOf("&L", StringComparison.Ordinal) >= 0)
                        {
                            pos = Math.Min(pos, text.IndexOf("&L", StringComparison.Ordinal));
                        }
                        _right = text.Substring(2, pos - 2);
                        text = text.Substring(pos);
                        break;
                    default:
                        _center = text;
                        break;
                }
            }
            return new String[] { _left, _center, _right, };
        }
        private void UpdatePart(int partIndex, String newValue)
        {
            String[] parts = SplitParts();
            parts[partIndex] = newValue == null ? "" : newValue;
            UpdateHeaderFooterText(parts);
        }
        /// <summary>
        /// Creates the complete footer string based on the left, center, and middle
        /// strings.
        /// </summary>
        /// <param name="parts">The parts.</param>
        private void UpdateHeaderFooterText(String[] parts)
        {
            String _left = parts[0];
            String _center = parts[1];
            String _right = parts[2];
 
            if (_center.Length < 1 && _left.Length < 1 && _right.Length < 1)
            {
                SetHeaderFooterText(string.Empty);
                return;
            }
            StringBuilder sb = new StringBuilder(64);
            sb.Append("&C");
            sb.Append(_center);
            sb.Append("&L");
            sb.Append(_left);
            sb.Append("&R");
            sb.Append(_right);
            String text = sb.ToString();
            SetHeaderFooterText(text);
        }
        protected HeaderFooter()
        {
 
        }
        /// <summary>
        /// Sets the header footer text.
        /// </summary>
        /// <param name="text">the new header footer text (contains mark-up tags). Possibly
        /// empty string never </param>
        protected abstract void SetHeaderFooterText(String text);
 
        /// <summary>
        /// Get the left side of the header or footer.
        /// </summary>
        /// <value>The string representing the left side.</value>
        public String Left 
        {
            get
            {
                return SplitParts()[0];
            }
            set 
            {
                UpdatePart(0, value); 
            }
        }
        /// <summary>
        /// Get the center of the header or footer.
        /// </summary>
        /// <value>The string representing the center.</value>
        public String Center
        {
            get
            {
                return SplitParts()[1];
            }
            set
            {
                UpdatePart(1, value);
            }
        }
 
        /// <summary>
        /// Get the right side of the header or footer.
        /// </summary>
        /// <value>The string representing the right side..</value>
        public String Right
        {
            get
            {
                return SplitParts()[2];
            }
            set
            {
                UpdatePart(2, value);
            }
        }
 
 
        /// <summary>
        /// Returns the string that represents the change in font size.
        /// </summary>
        /// <param name="size">the new font size.</param>
        /// <returns>The special string to represent a new font size</returns>
        public static String FontSize(short size)
        {
            return "&" + size;
        }
 
        /// <summary>
        /// Returns the string that represents the change in font.
        /// </summary>
        /// <param name="font">the new font.</param>
        /// <param name="style">the fonts style, one of regular, italic, bold, italic bold or bold italic.</param>
        /// <returns>The special string to represent a new font size</returns>
        public static String Font(String font, String style)
        {
            return "&\"" + font + "," + style + "\"";
        }
 
        /// <summary>
        /// Returns the string representing the current page number
        /// </summary>
        /// <value>The special string for page number.</value>
        public static String Page
        {
            get
            {
                return PAGE_FIELD.sequence;
            }
        }
 
        /// <summary>
        /// Returns the string representing the number of pages.
        /// </summary>
        /// <value>The special string for the number of pages.</value>
        public static String NumPages
        {
            get
            {
                return NUM_PAGES_FIELD.sequence;
            }
        }
 
        /// <summary>
        /// Returns the string representing the current date
        /// </summary>
        /// <value>The special string for the date</value>
        public static String Date
        {
            get
            {
                return DATE_FIELD.sequence;
            }
        }
 
        /// <summary>
        /// Gets the time.
        /// </summary>
        /// <value>The time.</value>
        /// Returns the string representing the current time
        /// @return The special string for the time
        public static String Time
        {
            get
            {
                return TIME_FIELD.sequence;
            }
        }
 
        /// <summary>
        /// Returns the string representing the current file name
        /// </summary>
        /// <value>The special string for the file name.</value>
        public static String File
        {
            get{
                return FILE_FIELD.sequence;
            }
        }
 
        /// <summary>
        /// Returns the string representing the current tab (sheet) name
        /// </summary>
        /// <value>The special string for tab name.</value>
        public static String Tab
        {
            get
            {
                return SHEET_NAME_FIELD.sequence;
            }
        }
 
        /// <summary>
        /// Returns the string representing the start bold
        /// </summary>
        /// <returns>The special string for start bold</returns>
        public static String StartBold
        {
            get
            {
                return BOLD_FIELD.sequence;
            }
        }
 
        /// <summary>
        /// Returns the string representing the end bold
        /// </summary>
        /// <value>The special string for end bold.</value>
        public static String EndBold
        {
            get
            {
                return BOLD_FIELD.sequence;
            }
        }
 
        /// <summary>
        /// Returns the string representing the start underline
        /// </summary>
        /// <value>The special string for start underline.</value>
        public static String StartUnderline
        {
            get
            {
                return UNDERLINE_FIELD.sequence;
            }
        }
 
        /// <summary>
        /// Returns the string representing the end underline
        /// </summary>
        /// <value>The special string for end underline.</value>
        public static String EndUnderline
        {
            get
            {
                return UNDERLINE_FIELD.sequence;
            }
        }
 
        /// <summary>
        /// Returns the string representing the start double underline
        /// </summary>
        /// <value>The special string for start double underline.</value>
        public static String StartDoubleUnderline
        {
            get
            {
                return DOUBLE_UNDERLINE_FIELD.sequence;
            }
        }
 
        /// <summary>
        /// Returns the string representing the end double underline
        /// </summary>
        /// <value>The special string for end double underline.</value>
        public static String EndDoubleUnderline
        {
            get
            {
                return DOUBLE_UNDERLINE_FIELD.sequence;
            }
        }
 
 
        /// <summary>
        /// Removes any fields (eg macros, page markers etc)
        /// from the string.
        /// Normally used to make some text suitable for showing
        /// to humans, and the resultant text should not normally
        /// be saved back into the document!
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns></returns>
        public static String StripFields(String text)
        {
            int pos;
 
            // Check we really got something to work on
            if (text == null || text.Length == 0)
            {
                return text;
            }
 
            foreach(Field field in Fields.AllFields)
            {
                String seq = field.sequence;
                while ((pos = text.IndexOf(seq, StringComparison.CurrentCulture)) > -1)
                {
                    text = text.Substring(0, pos) +
                        text.Substring(pos + seq.Length);
                }
            }
 
            // Now do the tricky, dynamic ones
            // These are things like font sizes and font names
 
            text = Regex.Replace(text,@"\&\d+", "");
            text = Regex.Replace(text,"\\&\".*?,.*?\"", "");
 
            // All done
            return text;
        }
 
 
        /// <summary>
        /// Are fields currently being Stripped from
        /// the text that this {@link HeaderStories} returns?
        /// Default is false, but can be changed
        /// </summary>
        /// <value><c>true</c> if [are fields stripped]; otherwise, <c>false</c>.</value>
        public bool AreFieldsStripped
        {
            get
            {
                return stripFields;
            }
            set 
            {
                this.stripFields = value; 
            }
        }
 
        // this abstract class does not initialize the static field that are required for the the StripFields method.
        public static Field SHEET_NAME_FIELD { get { return Fields.Instance.SHEET_NAME_FIELD; } }
        public static Field DATE_FIELD { get { return Fields.Instance.DATE_FIELD; } }
        public static Field FILE_FIELD { get { return Fields.Instance.FILE_FIELD; } }
        public static Field FULL_FILE_FIELD { get { return Fields.Instance.FULL_FILE_FIELD; } }
        public static Field PAGE_FIELD { get { return Fields.Instance.PAGE_FIELD; } }
        public static Field TIME_FIELD { get { return Fields.Instance.TIME_FIELD; } }
        public static Field NUM_PAGES_FIELD { get { return Fields.Instance.NUM_PAGES_FIELD; } }
 
        public static Field PICTURE_FIELD { get { return Fields.Instance.PICTURE_FIELD; } }
 
        public static PairField BOLD_FIELD { get { return Fields.Instance.BOLD_FIELD; } }
        public static PairField ITALIC_FIELD { get { return Fields.Instance.ITALIC_FIELD; } }
        public static PairField STRIKETHROUGH_FIELD { get { return Fields.Instance.STRIKETHROUGH_FIELD; } }
        public static PairField SUBSCRIPT_FIELD { get { return Fields.Instance.SUBSCRIPT_FIELD; } }
        public static PairField SUPERSCRIPT_FIELD { get { return Fields.Instance.SUPERSCRIPT_FIELD; } }
        public static PairField UNDERLINE_FIELD { get { return Fields.Instance.UNDERLINE_FIELD; } }
        public static PairField DOUBLE_UNDERLINE_FIELD { get { return Fields.Instance.DOUBLE_UNDERLINE_FIELD; } }
 
 
        /// <summary>
        /// Represents a special field in a header or footer,
        /// eg the page number
        /// </summary>
        public class Field
        {
            [Obsolete("Use the generic list Fields.AllFields instead.")]
            public static ArrayList ALL_FIELDS { get { return new ArrayList(Fields.AllFields); } }
 
            /** The character sequence that marks this field */
            public String sequence;
            public Field(Fields fields, String sequence)
            {
                this.sequence = sequence;
                fields.Add(this);
            }
 
 
        }
        /// <summary>
        /// A special field that normally comes in a pair, eg
        /// turn on underline / turn off underline
        /// </summary>
        public class PairField : Field
        {
            public PairField(Fields fields, String sequence)
                : base(fields, sequence)
            {
 
            }
        }
 
 
        public class Fields
        {
            private List<Field> allFields = new List<Field>();
            public static ReadOnlyCollection<Field> AllFields { get { return Instance.allFields.AsReadOnly(); } }
            private Field _sheetnamefield;
            private Field _filefield;
            private Field _fullfilefield;
            private Field _pagefield;
            private Field _datefield;
            private Field _timefield;
            private Field _numpagesfield;
            private Field _picturefield;
            private PairField _boldfield;
            private PairField _italicfield;
            private PairField _strikethroughfield;
            private PairField _subscriptfield;
            private PairField _superscriptfield;
            private PairField _underlinefield;
            private PairField _doubleunderlinefield;
            public Field SHEET_NAME_FIELD
            {
                get{return _sheetnamefield;}
            }
            public Field DATE_FIELD
            {
                get{return _datefield;}
            }
 
            public Field FILE_FIELD
            {
                get{return _filefield;}
            }
            public Field FULL_FILE_FIELD
            {
                get{return _fullfilefield;}
            }
 
            public Field PAGE_FIELD
            {
                get{return _pagefield;}
            }
            public Field TIME_FIELD
            {
                get{return _timefield;}
            }
            public Field NUM_PAGES_FIELD
            {
                get{return _numpagesfield;}
            }
 
            public Field PICTURE_FIELD
            {
                get{return _picturefield;}
            }
 
            public PairField BOLD_FIELD
            {
                get{return _boldfield;}
            }
            public PairField ITALIC_FIELD
            {
                get{return _italicfield;}
            }
            public PairField STRIKETHROUGH_FIELD
            {
                get{return _strikethroughfield;}
            }
            public PairField SUBSCRIPT_FIELD
            {
                get{return _subscriptfield;}
            }
            public PairField SUPERSCRIPT_FIELD
            {
                get{return _superscriptfield;}
            }
            public PairField UNDERLINE_FIELD
            {
                get{return _underlinefield;}
            }
            public PairField DOUBLE_UNDERLINE_FIELD
            {
                get{return _doubleunderlinefield;}
            }
 
 
            #region Singleton Implementation
            /// <summary>
            /// Instance to this class.
            /// </summary>
            static private readonly Fields instance = new Fields();
 
            /// <summary>
            /// Explicit static constructor to tell C# compiler not to mark type as beforefieldinit.
            /// </summary>
            static Fields()
            { }
 
            /// <summary>
            /// Initialize AllFields.
            /// </summary>
            private Fields()
            {
                _sheetnamefield = new Field(this, "&A");
                _datefield = new Field(this, "&D");
                _filefield  = new Field(this, "&F");
                _fullfilefield  = new Field(this, "&Z");
                _pagefield = new Field(this, "&P");
                _timefield = new Field(this, "&T");
                _numpagesfield = new Field(this, "&N");
 
                _picturefield = new Field(this, "&G");
 
                _boldfield = new PairField(this, "&B");
                _italicfield = new PairField(this, "&I");
                _strikethroughfield = new PairField(this, "&S");
                _subscriptfield = new PairField(this, "&Y");
                _superscriptfield = new PairField(this, "&X");
                _underlinefield = new PairField(this, "&U");
                _doubleunderlinefield = new PairField(this, "&E");
            }
 
            /// <summary>
            /// Accessing the initialized instance.
            /// </summary>
            public static Fields Instance
            {
                get
                {
                    return instance;
                }
            }
            #endregion Singleton Implementation
 
            internal void Add(Field field)
            {
                allFields.Add(field);
            }
        }
 
 
    }
}