郑永安
2023-06-19 59e91a4e9ddaf23cebb12993c774aa899ab22d16
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
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
package com.gk.firework.Domain.Utils;
 
import com.gk.firework.Domain.Exception.BusinessException;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcBorders;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
 
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.RenderedImage;
import java.io.*;
import java.util.*;
import java.util.List;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
 
public class WordTemplate {
 
    private XWPFDocument document;
 
 
    public void loadTemplate(File file,InputStream in) throws IOException{
        //File file = new File(fileName);
        InputStream target = null;
        if (file != null) {
            target =  new FileInputStream(file);
        }else{
            target = in;
        }
        try{
            document = new XWPFDocument(target);
            target.close();
        } catch(IOException ex){
            if(target != null){
                target.close();
            }
            throw ex;
        }
    }
 
    public void saveFile(String fileName) throws IOException {
//        File outputFile=new File(fileName);//filename=D:\Users\inner_peace\Downloads
//        if(!outputFile.exists()){//判断outputFile这个文件夹是否存在,不存在,创建文件夹(Tips:使用mkdirs创建多层目录,而不是mkdir创建单一目录)
//            System.out.println("start");
//            outputFile.mkdirs();
//            System.out.println("end");
//        }
        File f=new File(fileName);
        String a="";
        if(!f.exists()){//判断outputFile文件夹下是否存在name文件,不存在,创建
            f.createNewFile();
        }/*else{//存在,需要重新创建一个不同名字的文件,这边暂时是在文件名称后不断加(01)
            String xx=name.substring(0,name.length()-5);
            a=xx+"(1)";
        }*/
        /*File ff=new File(fileName+a+".docx");
        ff.createNewFile();
        System.out.println(43);*/
        FileOutputStream fos  = new FileOutputStream(f);
        try{
            document.write(fos);
            fos.close();
        }catch (IOException ex){
            if(fos != null){
                fos.close();
            }
            throw ex;
        }
    }
 
    public void saveFileAndQRCode(String fileName,String info) throws IOException {
        File f=new File(fileName);
        if(!f.exists()){
            f.createNewFile();
        }
        FileOutputStream fos  = new FileOutputStream(f);
 
        try{
            Image image = QRCode.generateQRCode(info);
            //
            String QRCodeUrl = Properties.transportCertificatePath + info + "_" + "QRCode.png";
            File file = new File(QRCodeUrl);
            if (!file.exists()) {file.createNewFile();}
 
            ImageIO.write((RenderedImage) image, "png", file);
                List<XWPFParagraph> paragraphs = document.getParagraphs();
                for (int i = 0; i < paragraphs.size(); i++) {
                    XWPFParagraph paragraph = paragraphs.get(i);
                    List<XWPFRun> runs = paragraph.getRuns();
                    for (int l = 0; l < runs.size(); l++) {
                        XWPFRun run = runs.get(l);
                        if (run.text().equals("") || run.text().equals("/n")) {
                            continue;
                        }
                        if (run.text().equals("#QRCode#")) {//如果遍历到标记位置退出循环,并记录一下标记位置所在段落对象的下标
                            paragraph.removeRun(l);//同时把正文两字移除
                            XWPFRun xwpfRun = paragraph.insertNewRun(l);
                            xwpfRun.addPicture( new FileInputStream(file),XWPFDocument.PICTURE_TYPE_PNG,"QRCode.png", Units.toEMU(40), Units.toEMU(40));
                            paragraph.addRun(xwpfRun);
                        }else if (run.text().contains("第一联") || run.text().contains("第二联") ) {
                            if (i + 1 < paragraphs.size()) {
                                paragraphs.get(i + 1).setPageBreak(true );
                            }
 
                        }
                    }
                }
 
            document.write(fos);
        }catch (IOException ex){
            ex.printStackTrace();
            throw new BusinessException("生成文件发生错误");
        }  catch (InvalidFormatException e) {
            e.printStackTrace();
            throw new BusinessException("格式不合法");
        }finally {
            fos.close();
        }
    }
 
    public static class Table{
        private String[] fields;
        List<String[]> data;
        HashMap<String,Integer> index;
        public Table(String[] fields,List<String[]> data){
            this.fields = fields;
            this.data = data;
            this.index = new HashMap<String,Integer>();
            for(int i=0 ; i<fields.length; i++){
                this.index.put(fields[i],i);
            }
        }
    }
 
 
 
    public void replaceDocument(Map<String, Table> tableMap,Map<String,String> paraMap) {
        List<IBodyElement> bodyElements = document.getBodyElements();
        int templateBodySize = bodyElements.size();
        int curT = 0;
        int curP = 0;
        for (int a = 0; a < templateBodySize; a++) {
 
            IBodyElement body = bodyElements.get(a);
            //  System.out.println( body.getElementType());
            if (BodyElementType.TABLE.equals(body.getElementType())) {
                //
                XWPFTable table = body.getBody().getTableArray(curT);
                List<XWPFTable> tables = body.getBody().getTables();
                table = tables.get(curT);
                if (table != null) {
                    List<XWPFTableCell> tableCells = table.getRows().get(0).getTableCells();
                    // 获取到模板表格第一行,用来判断表格类型
                    String tableText = table.getText();
                    if (tableText.indexOf("##{foreach") > -1) {
                        if (tableCells.size() != 2
                                || tableCells.get(0).getText().indexOf("##{foreach") < 0
                                || tableCells.get(0).getText().trim().length() == 0) {
                            throw new RuntimeException("need two cell in row.");
                        }
 
                        String tableType = tableCells.get(0).getText();
                        String dataSource = tableCells.get(1).getText();
 
                        if (!tableMap.containsKey(dataSource)) {
                            throw new RuntimeException("need table:" + dataSource);
                        }
                        Table tableData = tableMap.get(dataSource);
 
                        if ("##{foreachTable}##".equals(tableType)) {
                            // System.out.println("循环生成表格");
                            addTableInDocFooterByTable(table, tableData);
 
                        } else if ("##{foreachTableRow}##".equals(tableType)) {
                            // System.out.println("循环生成表格内部的行");
                            addTableInDocFooterByRow(table, tableData, paraMap);
                        }
 
                    } else if (tableText.indexOf("{") > -1) {
                        addTableInDocFooterByParas(table, paraMap);
 
                    } else {
                        // 没有查找到任何标签,该表格是一个静态表格,仅需要复制一个即可。
                        addTableInDocFooterByOrigin(table);
                    }
                    curT++;
 
                }
            } else if (BodyElementType.PARAGRAPH.equals(body.getElementType())) {// 处理段落
                XWPFParagraph ph = body.getBody().getParagraphArray(curP);
                if (ph != null) {
                    // htmlText = htmlText+readParagraphX(ph);
                    addParagraphInDocFooter(ph, null, paraMap);
                    curP++;
                }
            } else if (BodyElementType.CONTENTCONTROL.equals(body.getElementType())) {
                IBodyElement bodyElement = bodyElements.get(curP);
                IBody body1 = bodyElement.getBody();
            }
        }
 
        for (int a = 0; a < templateBodySize; a++) {
            document.removeBodyElement(0);
        }
 
    }
 
    //
    public void replaceDocument2(Map<String, Table> cellMap,Map<String,String> params) throws IOException, XmlException {
        List<IBodyElement> bodyElements = document.getBodyElements();
        int templateBodySize = bodyElements.size();
        int curT = 0;
        for (int a = 0; a < templateBodySize; a++) {
 
            IBodyElement body = bodyElements.get(a);
            //  System.out.println( body.getElementType());
            if (BodyElementType.TABLE.equals(body.getElementType())) {
                //
                XWPFTable table = body.getBody().getTableArray(curT);
                List<XWPFTable> tables = body.getBody().getTables();
                POIXMLDocumentPart part = body.getBody().getPart();
                table = tables.get(curT);
                Table mainTable = cellMap.get("mainTable");
                List<String[]> data = mainTable.data;
                int remove = 0;
 
                List<XWPFTableRow> rows = table.getRows();
                for (int i = 0; i < rows.size(); i++) {
                    XWPFTableRow row = rows.get(i);
                    List<XWPFTableCell> tableCells = row.getTableCells();
                    for (int j = 0; j < tableCells.size(); j++) {
                        XWPFTableCell cell = tableCells.get(j);
                        String text = cell.getText();
                        if (params.get(text) != null) {
                            cell.removeParagraph(0);
                            cell.setText(params.get(text));
                        }
                        //生成表内容
                        if ("##foreachRows##".equals(cell.getText())) {
                            //从下面一行开始循环生成单元格
                            XWPFTableRow infoRow = rows.get(i + 1);
                            for (int k = 0; k < mainTable.data.size(); k++) {
                                CTRow ctrow = CTRow.Factory.parse(infoRow.getCtRow().newInputStream());
                                XWPFTableRow newRow = new XWPFTableRow(ctrow, table);
                                String[] strings = data.get(k);
                                for (int m = 0; m < strings.length; m++)
                                {
                                    XWPFTableCell cellSS = newRow.getTableCells().get(m);// 在新增的行上面创建cell
                                    //cell.setText(fields.get(k));//不能使用该方法直接加内容,这样会在原内容后面追加,并且不能保证跟原字体样式一致
                                    for (XWPFParagraph p : cellSS.getParagraphs())
                                    {
                                        for (XWPFRun r : p.getRuns())
                                        {
                                            r.setText(strings[m], 0);//要深入到原cell中的run替换内容才能保证样式一致
                                        }
                                    }
                                }
                                table.addRow(newRow, i + k);
                            }
                            //删除####foreachRows##这一行
                            table.removeRow(i + mainTable.data.size());
                            //删除type    specification    num 这一行
                            table.removeRow(i + mainTable.data.size());
                        }
                    }
                }
 
 
            }
        }
 
    }
 
    private void addTableInDocFooterByTable(XWPFTable templateTable, Table data) {
        for (String[] row: data.data) {
            List<XWPFTableRow> templateTableRows = templateTable.getRows();// 获取模板表格所有行
            XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列
            for (int i = 1; i < templateTableRows.size(); i++) {
                XWPFTableRow newCreateRow = newCreateTable.createRow();
                CopyTableRow(newCreateRow, templateTableRows.get(i));// 复制模板行文本和样式到新行
            }
            newCreateTable.removeRow(0);// 移除多出来的第一行
            document.createParagraph();// 添加回车换行
            replaceTable(newCreateTable, getMap(data.index,row));//替换标签
        }
    }
 
    private HashMap getMap(HashMap<String,Integer> key,String[] row){
        HashMap<String,String> r = new HashMap<String,String>();
        Iterator<Entry<String, Integer>>  it =key.entrySet().iterator();
        while(it.hasNext()){
            Entry<String, Integer> en =it.next();
            r.put(en.getKey(),row[en.getValue()]);
        }
        return r;
    }
    private void addTableInDocFooterByRow(XWPFTable templateTable, Table data , Map<String, String> parametersMap) {
 
        XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列
        List<XWPFTableRow> TempTableRows = templateTable.getRows();// 获取模板表格所有行
        int tagRowsIndex = 0;// 标签行indexs
        for (int i = 0, size = TempTableRows.size(); i < size; i++) {
            String rowText = TempTableRows.get(i).getCell(0).getText();// 获取到表格行的第一个单元格
            if (rowText.indexOf("##{foreachRows}##") > -1) {
                tagRowsIndex = i;
                break;
            }
        }
 
        /* 复制模板行和标签行之前的行 */
        for (int i = 1; i < tagRowsIndex; i++) {
            XWPFTableRow newCreateRow = newCreateTable.createRow();
            CopyTableRow(newCreateRow, TempTableRows.get(i));// 复制行
            replaceTableRow(newCreateRow, parametersMap);// 处理不循环标签的替换
        }
 
        /* 循环生成模板行 */
        XWPFTableRow tempRow = TempTableRows.get(tagRowsIndex + 1);// 获取到模板行
        for (String[] row: data.data) {
            XWPFTableRow newCreateRow = newCreateTable.createRow();
            CopyTableRow(newCreateRow, tempRow);// 复制模板行
            replaceTable(newCreateTable, getMap(data.index,row));//替换标签
        }
 
        /* 复制模板行和标签行之后的行 */
        for (int i = tagRowsIndex + 2; i < TempTableRows.size(); i++) {
            XWPFTableRow newCreateRow = newCreateTable.createRow();
            CopyTableRow(newCreateRow, TempTableRows.get(i));// 复制行
            replaceTableRow(newCreateRow, parametersMap);// 处理不循环标签的替换
        }
        newCreateTable.removeRow(0);// 移除多出来的第一行
        document.createParagraph();// 添加回车换行
 
    }
 
    private void addTableInDocFooterByOrigin(XWPFTable templateTable
    ) {
        List<XWPFTableRow> templateTableRows = templateTable.getRows();// 获取模板表格所有行
        XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列
        for (int i = 0; i < templateTableRows.size(); i++) {
            XWPFTableRow newCreateRow = newCreateTable.createRow();
            CopyTableRow(newCreateRow, templateTableRows.get(i));// 复制模板行文本和样式到新行
        }
        newCreateTable.removeRow(0);// 移除多出来的第一行
        document.createParagraph();// 添加回车换行
    }
 
 
    private void addTableInDocFooterByParas(XWPFTable templateTable,
                                            Map<String, String> parametersMap) {
        //表格不循环仅简单替换标签
        List<XWPFTableRow> templateTableRows = templateTable.getRows();// 获取模板表格所有行
        XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列
        for (int i = 0; i < templateTableRows.size(); i++) {
            XWPFTableRow newCreateRow = newCreateTable.createRow();
            CopyTableRow(newCreateRow, templateTableRows.get(i));// 复制模板行文本和样式到新行
        }
        newCreateTable.removeRow(0);// 移除多出来的第一行
        // document.createParagraph();// 添加回车换行
        replaceTable(newCreateTable, parametersMap);
    }
 
 
 
    private void addParagraphInDocFooter(XWPFParagraph templateParagraph,
                                         List<Map<String, String>> list, Map<String, String> parametersMap) {
        XWPFParagraph createParagraph = document.createParagraph();
        // 设置段落样式
        createParagraph.getCTP().setPPr(templateParagraph.getCTP().getPPr());
        // 移除原始内容
        for (int pos = 0; pos < createParagraph.getRuns().size(); pos++) {
            createParagraph.removeRun(pos);
        }
        // 添加Run标签
        for (XWPFRun s : templateParagraph.getRuns()) {
            XWPFRun targetrun = createParagraph.createRun();
            CopyRun(targetrun, s);
        }
 
        replaceParagraph(createParagraph, parametersMap);
    }
 
    private void replaceParagraph(XWPFParagraph xWPFParagraph, Map<String, String> parametersMap) {
        List<XWPFRun> runs = xWPFParagraph.getRuns();
        String xWPFParagraphText = xWPFParagraph.getText();
        String regEx = "\\{.+?\\}";
        Pattern pattern = Pattern.compile(regEx);
        Matcher matcher = pattern.matcher(xWPFParagraphText);//正则匹配字符串{****}
 
        if (matcher.find()) {
            // 查找到有标签才执行替换
            int beginRunIndex = xWPFParagraph.searchText("{", new PositionInParagraph()).getBeginRun();// 标签开始run位置
            int endRunIndex = xWPFParagraph.searchText("}", new PositionInParagraph()).getEndRun();// 结束标签
            StringBuffer key = new StringBuffer();
 
            if (beginRunIndex == endRunIndex) {
                // {**}在一个run标签内
                XWPFRun beginRun = runs.get(beginRunIndex);
                String beginRunText = beginRun.text();
 
                int beginIndex = beginRunText.indexOf("{");
                int endIndex = beginRunText.indexOf("}");
                int length = beginRunText.length();
 
                if (beginIndex == 0 && endIndex == length - 1) {
                    // 该run标签只有{**}
                    XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex);
                    insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr());
                    // 设置文本
                    key.append(beginRunText.substring(1, endIndex));
                    insertNewRun.setText(getValueBykey(key.toString(),parametersMap));
                    xWPFParagraph.removeRun(beginRunIndex + 1);
                } else {
                    // 该run标签为**{**}** 或者 **{**} 或者{**}**,替换key后,还需要加上原始key前后的文本
                    XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex);
                    insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr());
                    // 设置文本
                    key.append(beginRunText.substring(beginRunText.indexOf("{")+1, beginRunText.indexOf("}")));
                    String textString=beginRunText.substring(0, beginIndex) + getValueBykey(key.toString(),parametersMap)
                            + beginRunText.substring(endIndex + 1);
                    insertNewRun.setText(textString);
                    xWPFParagraph.removeRun(beginRunIndex + 1);
                }
 
            }else {
                // {**}被分成多个run
 
                //先处理起始run标签,取得第一个{key}值
                XWPFRun beginRun = runs.get(beginRunIndex);
                String beginRunText = beginRun.text();
                int beginIndex = beginRunText.indexOf("{");
                if (beginRunText.length()>1  ) {
                    key.append(beginRunText.substring(beginIndex+1));
                }
                ArrayList<Integer> removeRunList = new ArrayList<>();//需要移除的run
                //处理中间的run
                for (int i = beginRunIndex + 1; i < endRunIndex; i++) {
                    XWPFRun run = runs.get(i);
                    String runText = run.text();
                    key.append(runText);
                    removeRunList.add(i);
                }
 
                // 获取endRun中的key值
                XWPFRun endRun = runs.get(endRunIndex);
                String endRunText = endRun.text();
                int endIndex = endRunText.indexOf("}");
                //run中**}或者**}**
                if (endRunText.length()>1 && endIndex!=0) {
                    key.append(endRunText.substring(0,endIndex));
                }
 
 
 
                //*******************************************************************
                //取得key值后替换标签
 
                //先处理开始标签
                if (beginRunText.length()==2 ) {
                    // run标签内文本{
                    XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex);
                    insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr());
                    // 设置文本
                    insertNewRun.setText(getValueBykey(key.toString(),parametersMap));
                    xWPFParagraph.removeRun(beginRunIndex + 1);//移除原始的run
                }else {
                    // 该run标签为**{**或者 {** ,替换key后,还需要加上原始key前的文本
                    XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex);
                    insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr());
                    // 设置文本
                    String textString=beginRunText.substring(0,beginRunText.indexOf("{"))+getValueBykey(key.toString(),parametersMap);
                    insertNewRun.setText(textString);
                    xWPFParagraph.removeRun(beginRunIndex + 1);//移除原始的run
                }
 
                //处理结束标签
                if (endRunText.length()==1 ) {
                    // run标签内文本只有}
                    XWPFRun insertNewRun = xWPFParagraph.insertNewRun(endRunIndex);
                    insertNewRun.getCTR().setRPr(endRun.getCTR().getRPr());
                    // 设置文本
                    insertNewRun.setText("");
                    xWPFParagraph.removeRun(endRunIndex + 1);//移除原始的run
 
                }else {
                    // 该run标签为**}**或者 }** 或者**},替换key后,还需要加上原始key后的文本
                    XWPFRun insertNewRun = xWPFParagraph.insertNewRun(endRunIndex);
                    insertNewRun.getCTR().setRPr(endRun.getCTR().getRPr());
                    // 设置文本
                    String textString=endRunText.substring(endRunText.indexOf("}")+1);
                    insertNewRun.setText(textString);
                    xWPFParagraph.removeRun(endRunIndex + 1);//移除原始的run
                }
 
                //处理中间的run标签
                for (int i = 0; i < removeRunList.size(); i++) {
                    XWPFRun xWPFRun = runs.get(removeRunList.get(i));//原始run
                    XWPFRun insertNewRun = xWPFParagraph.insertNewRun(removeRunList.get(i));
                    insertNewRun.getCTR().setRPr(xWPFRun.getCTR().getRPr());
                    insertNewRun.setText("");
                    xWPFParagraph.removeRun(removeRunList.get(i) + 1);//移除原始的run
                }
 
            }// 处理${**}被分成多个run
 
            replaceParagraph( xWPFParagraph, parametersMap);
 
        }//if 有标签
 
    }
 
 
 
 
 
 
 
 
    /**
     * 复制表格行XWPFTableRow格式
     *
     * @param target
     *            待修改格式的XWPFTableRow
     * @param source
     *            模板XWPFTableRow
     */
    private void CopyTableRow(XWPFTableRow target, XWPFTableRow source) {
 
        int tempRowCellsize = source.getTableCells().size();// 模板行的列数
        for (int i = 0; i < tempRowCellsize - 1; i++) {
            target.addNewTableCell();// 为新添加的行添加与模板表格对应行行相同个数的单元格
        }
        // 复制样式
        target.getCtRow().setTrPr(source.getCtRow().getTrPr());
        // 复制单元格
        for (int i = 0; i < target.getTableCells().size(); i++) {
            copyTableCell(target.getCell(i), source.getCell(i));
        }
    }
 
 
 
 
 
    /**
     * 复制单元格XWPFTableCell格式
     *
     * @author Juveniless
     * @date 2017年11月27日 下午3:41:02
     * @param newTableCell
     *            新创建的的单元格
     * @param templateTableCell
     *            模板单元格
     *
     */
    private void copyTableCell(XWPFTableCell newTableCell, XWPFTableCell templateTableCell) {
        // 列属性
        newTableCell.getCTTc().setTcPr(templateTableCell.getCTTc().getTcPr());
 
        if(templateTableCell.getText().indexOf("{noborder}")>-1){
            CTTcBorders tblBorders = newTableCell.getCTTc().getTcPr().addNewTcBorders();
            tblBorders.addNewLeft().setVal(STBorder.NIL);
            tblBorders.addNewRight().setVal(STBorder.NIL);
            tblBorders.addNewTop().setVal(STBorder.NIL);
            newTableCell.getCTTc().getTcPr().setTcBorders(tblBorders);
        }
 
        // 删除目标 targetCell 所有文本段落
        for (int pos = 0; pos < newTableCell.getParagraphs().size(); pos++) {
            newTableCell.removeParagraph(pos);
        }
        // 添加新文本段落
        for (XWPFParagraph sp : templateTableCell.getParagraphs()) {
            XWPFParagraph targetP = newTableCell.addParagraph();
            copyParagraph(targetP, sp);
        }
    }
 
    /**
     * 复制文本段落XWPFParagraph格式
     *
     * @author Juveniless
     * @date 2017年11月27日 下午3:43:08
     * @param newParagraph
     *            新创建的的段落
     * @param templateParagraph
     *            模板段落
     *
     */
    private void copyParagraph(XWPFParagraph newParagraph, XWPFParagraph templateParagraph) {
        // 设置段落样式
        newParagraph.getCTP().setPPr(templateParagraph.getCTP().getPPr());
        // 添加Run标签
        for (int pos = 0; pos < newParagraph.getRuns().size(); pos++) {
            newParagraph.removeRun(pos);
 
        }
        for (XWPFRun s : templateParagraph.getRuns()) {
            XWPFRun targetrun = newParagraph.createRun();
            CopyRun(targetrun, s);
        }
 
    }
 
    /**
     * 复制文本节点run
     * @author Juveniless
     * @date 2017年11月27日 下午3:47:17
     * @param newRun
     *            新创建的的文本节点
     * @param templateRun
     *            模板文本节点
     *
     */
    private void CopyRun(XWPFRun newRun, XWPFRun templateRun) {
        newRun.getCTR().setRPr(templateRun.getCTR().getRPr());
        // 设置文本
        newRun.setText(templateRun.text());
    }
 
 
 
    private void replaceTableRow(XWPFTableRow tableRow, Map<String, String> parametersMap) {
 
        List<XWPFTableCell> tableCells = tableRow.getTableCells();
        for (XWPFTableCell xWPFTableCell : tableCells) {
            List<XWPFParagraph> paragraphs = xWPFTableCell.getParagraphs();
            for (XWPFParagraph xwpfParagraph : paragraphs) {
 
                replaceParagraph(xwpfParagraph, parametersMap);
            }
        }
 
    }
 
 
    private void replaceTable(XWPFTable xwpfTable, Map<String, String> parametersMap){
        List<XWPFTableRow> rows = xwpfTable.getRows();
        for (XWPFTableRow xWPFTableRow : rows ) {
            List<XWPFTableCell> tableCells = xWPFTableRow.getTableCells();
            for (XWPFTableCell xWPFTableCell : tableCells ) {
                List<XWPFParagraph> paragraphs2 = xWPFTableCell.getParagraphs();
                for (XWPFParagraph xWPFParagraph : paragraphs2) {
                    replaceParagraph(xWPFParagraph, parametersMap);
                }
            }
        }
 
    }
 
    private String getValueBykey(String key, Map<String, String> map) {
        String returnValue="";
        if (key != null) {
            key = key.trim();
            try {
                returnValue=map.get(key)!=null ? map.get(key).toString() : "";
            } catch (Exception e) {
 
                returnValue="";
            }
        }
        // System.out.println(key+":" + returnValue);
        return returnValue;
    }
 
 
 
 
 
 
 
 
}