POI 操作word

关于POI 操作word的基础知识在这个博客(http://elim.iteye.com/blog/2049110)中有非常清晰的解释,在这里我就不多解释了 
本文研究的内容就是 
XWPFParagraph:代表一个段落

XWPFRun:代表具有相同属性的一段文本

大家都知道在设计模式中有个构造器模式,用于那些拥有很多属性但是有些属性可选设置的对象的生成。笔者觉得段落和文本的构建能很好运用此种模式。

首先是段落构建器

    //段落构建器
    public class XWPFParagraphBuilder {
        //常量,在文档中定义长度和高度的单位
        private static final int PER_LINE = 100;
        //每个字符的单位长度
        private static final int PER_CHART = 100;
        //1厘米≈567
        private static final int PER_CM = 567;
        //每一磅的单位长度
        private static final int PER_POUND = 20;
        //行距单位长度
        private static final int ONE_LINE = 240;

        private XWPFParagraph paragraph = null;
        private CTPPr pPr = null;
        //保存通用段落属性引用,方便复用
        private Map<String, CTPPr> savedPPr = null;
        //设定间距的对象
        private CTSpacing pSpacing = null;
        //设定缩进的对象
        private CTInd pInd = null;


        public XWPFParagraphBuilder init(XWPFDocument document) {
            return init(document.createParagraph());
        }

        public XWPFParagraphBuilder init(XWPFParagraph paragraph) {
            if (paragraph == null) {
                throw new IllegalArgumentException("the paragraph should not be null");
            }
            this.paragraph = paragraph;
            pPr = getPrOfParagraph(paragraph);
            return this;
        }

        //设置段落对齐方式
        public XWPFParagraphBuilder align(ParagraphAlignment pAlign, TextAlignment vAlign) {
            ensureInit();
            if (pAlign != null) {
                paragraph.setAlignment(pAlign);
            }
            if (vAlign != null) {
                paragraph.setVerticalAlignment(vAlign);
            }
            return this;
        }

        //初始化段落间距属性,在设置各段落间距前调用
        public XWPFParagraphBuilder initSpacing() {
            ensureInit();
            pSpacing = pPr.getSpacing() != null ? pPr.getSpacing() : pPr.addNewSpacing();
            return this;
        }

        //设置段前和段后间距,以磅为单位
        public XWPFParagraphBuilder spaceInPound(double before, double after) {
            ensureInit();
            if (pSpacing == null) {
                initSpacing();
            }
            pSpacing.setBefore(BigInteger.valueOf((long) (before * PER_POUND)));
            pSpacing.setAfter(BigInteger.valueOf((long) (after * PER_POUND)));
            return this;
        }

        //设置段前和段后间距,以行为单位
        public XWPFParagraphBuilder spaceInLine(double beforeLines, double afterLines) {
            ensureInit();
            if (pSpacing == null) {
                initSpacing();
            }
            pSpacing.setBeforeLines(BigInteger.valueOf((long) (beforeLines * PER_LINE)));
            pSpacing.setAfterLines(BigInteger.valueOf((long) (afterLines * PER_LINE)));
            return this;
        }

        //设置段落行距
        public XWPFParagraphBuilder lineSpace(double value, STLineSpacingRule.Enum spaceRule) {
            ensureInit();
            if (pSpacing == null) {
                initSpacing();
            }
            int unit;
            if (spaceRule == null) {
                spaceRule = STLineSpacingRule.AUTO;
            }
            if (spaceRule.intValue() == STLineSpacingRule.INT_AUTO) {
                //当行距规则为多倍行距时,单位为行,且最小为0.06行
                unit = ONE_LINE;
                if (value < 0.06) {
                    value = 0.06;
                }
            } else {
                //当行距规则为固定值或最小值时,单位为磅,且最小为0.7磅
                unit = PER_POUND;
                if (value < 0.7) {
                    value = 0.7;
                }
            }
            pSpacing.setLine(BigInteger.valueOf((long) (value * unit)));
            pSpacing.setLineRule(spaceRule);
            return this;
        }

        public XWPFParagraphBuilder initInd() {
            ensureInit();
            pInd = pPr.getInd() != null ? pPr.getInd() : pPr.addNewInd();
            return this;
        }

        //设置段落缩进,以厘米为单位; 悬挂缩进高于首行缩进;右侧缩进高于左侧缩进
        public XWPFParagraphBuilder indentInCM(double firstLine, double hanging, double right, double left) {
            ensureInit();
            if (pInd == null) {
                initInd();
            }
            if (firstLine != 0) {
                pInd.setFirstLine(BigInteger.valueOf((long) (firstLine * PER_CM)));
            }
            if (hanging != 0) {
                pInd.setHanging(BigInteger.valueOf((long) (hanging * PER_CM)));
            }
            if (right != 0) {
                pInd.setRight(BigInteger.valueOf((long) (right * PER_CM)));
            }
            if (left != 0) {
                pInd.setLeft(BigInteger.valueOf((long) (left * PER_CM)));
            }
            return this;
        }

        //设置段落缩进,以字符为单位; 悬挂缩进高于首行缩进;右侧缩进高于左侧缩进
        public XWPFParagraphBuilder indentInChart(int firstLine, int hanging, int left, int right) {
            ensureInit();
            if (pInd == null) {
                initInd();
            }
            if (firstLine != 0) {
                pInd.setFirstLineChars(BigInteger.valueOf((long) (firstLine * PER_CHART)));
            }
            if (hanging != 0) {
                pInd.setHangingChars(BigInteger.valueOf((long) (hanging * PER_CHART)));
            }
            if (right != 0) {
                pInd.setRightChars(BigInteger.valueOf((long) (right * PER_CHART)));
            }
            if (left != 0) {
                pInd.setLeftChars(BigInteger.valueOf((long) (left * PER_CHART)));
            }
            return this;
        }

        public XWPFParagraphBuilder savePr(String pPrName) {
            ensureInit();
            if (savedPPr == null) {
                savedPPr = new HashedMap<String, CTPPr>();
            }

            savedPPr.put(pPrName, pPr);

            return this;
        }

        public XWPFParagraphBuilder samePrOf(String pPrName) {
            ensureInit();

            if (savedPPr != null && savedPPr.containsKey(pPrName)) {
                return samePrOf(savedPPr.get(pPrName));
            }

            return this;
        }

        public XWPFParagraphBuilder samePrOf(CTPPr pPr) {
            ensureInit();
            if (pPr != null) {
                paragraph.getCTP().setPPr(pPr);
            }
            return this;
        }

        public XWPFParagraphBuilder samePrOf(XWPFParagraph otherPra) {
            ensureInit();
            paragraph.getCTP().setPPr(getPrOfParagraph(otherPra));
            return this;
        }

        public XWPFParagraph build() {
            return paragraph;
        }

        //确保init方法是第一个调用的,避免出现空指针异常
        private void ensureInit() {
            if (this.paragraph == null) {
                throw new IllegalStateException("the init method must be invoked firstly");
            }
        }
    }
  • 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

构建器的优点在于能够链式调用 
示例:

        //新增一个段前2倍行距段后3倍行距,文本2倍行距的段落
        XWPFParagraph firstPar = paragraphBuilder.init(document).initSpacing().spaceInLine(2, 3)
                    .lineSpace(2, null).build();
  • 1
  • 2
  • 3

如果有一段段落的属性与之前段落相同,你可以在链尾调用savePr(String pPrName),来为保存该属性,并制定名称,当有其他段落要用到次属性时就可以在调用samePrOf(String pPrName)来设定属性避免重复操作。

其中有一点需要注意的是:init方法一定是第一个调用的,不然会出现空指针异常

接下来是文本构建器(思想与段落相同)

    //文本构建器
    public class XWPFRunBuilder {
        private XWPFRun run = null;
        private Map<String, CTRPr> savedRPr;

        public XWPFRunBuilder init(XWPFParagraph paragraph) {
            return init(paragraph, false);
        }

        public XWPFRunBuilder init(XWPFParagraph paragraph, boolean newLine) {
            this.run = paragraph.createRun();
            if (newLine) {
                run.addBreak();
            }
            return this;
        }

        /**
         * insert a new Run in RunArray
         *
         * @param pos The position at which the new run should be added.
         */
        public XWPFRunBuilder init(XWPFParagraph paragraph, int pos) {
            this.run = paragraph.insertNewRun(pos);
            if (this.run == null) {
                return init(paragraph, false);
            }
            return this;
        }

        public XWPFRunBuilder init(XWPFRun run) {
            if (run == null) {
                throw new IllegalArgumentException("the run should not be null");
            }
            this.run = run;
            return this;
        }

        public XWPFRunBuilder content(String content) {
            ensureInit();
            if (StringUtils.isNotBlank(content)) {
                // pRun.setText(content);
                if (content.contains("\n")) {// System.properties("line.separator")
                    String[] lines = content.split("\n");
                    run.setText(lines[0], 0); // set first line into XWPFRun
                    for (int i = 1; i < lines.length; i++) {
                        // add break and insert new text
                        run.addBreak();
                        run.setText(lines[i]);
                    }
                } else {
                    run.setText(content, 0);
                }
            }
            return this;
        }

        //加粗
        public XWPFRunBuilder bold(boolean bold) {
            ensureInit();
            run.setBold(bold);
            return this;
        }

        //斜体
        public XWPFRunBuilder italic(boolean italic) {
            ensureInit();
            run.setItalic(italic);
            return this;
        }

        //删除线
        public XWPFRunBuilder strike(boolean strike) {
            ensureInit();
            run.setStrike(strike);
            return this;
        }

        //字体设置,中文字体、英文字体、字号
        public XWPFRunBuilder font(String cnFontFamily, String enFontFamily, String fontSize) {
            ensureInit();
            CTRPr rPr = getPrOfRun(run);
            // 设置字体
            CTFonts fonts = rPr.isSetRFonts() ? rPr.getRFonts() : rPr.addNewRFonts();
            if (StringUtils.isNotBlank(enFontFamily)) {
                fonts.setAscii(enFontFamily);
                fonts.setHAnsi(enFontFamily);
            }
            if (StringUtils.isNotBlank(cnFontFamily)) {
                fonts.setEastAsia(cnFontFamily);
                fonts.setHint(STHint.EAST_ASIA);
            }
            // 设置字体大小
            CTHpsMeasure sz = rPr.isSetSz() ? rPr.getSz() : rPr.addNewSz();
            sz.setVal(new BigInteger(fontSize));

            CTHpsMeasure szCs = rPr.isSetSzCs() ? rPr.getSzCs() : rPr
                    .addNewSzCs();
            szCs.setVal(new BigInteger(fontSize));
            return this;
        }

        //底纹
        public XWPFRunBuilder shade(STShd.Enum shdStyle, String shdColor) {
            ensureInit();
            CTRPr rPr = getPrOfRun(run);
            // 设置底纹
            CTShd shd = rPr.isSetShd() ? rPr.getShd() : rPr.addNewShd();
            if (shdStyle != null) {
                shd.setVal(shdStyle);
            }
            if (shdColor != null) {
                shd.setColor(shdColor);
                shd.setFill(shdColor);
            }
            return this;
        }

        /**
         * @param position 字符垂直方向上间距位置; >0:提升; <0:降低;=磅值*2
         * @return
         */
        public XWPFRunBuilder position(int position) {
            ensureInit();
            if (position != 0) {
                run.setTextPosition(position);
            }
            return this;
        }

        //字符间距
        public XWPFRunBuilder space(int spacingValue) {
            ensureInit();
            if (spacingValue > 0) {
                CTRPr rPr = getPrOfRun(run);
                CTSignedTwipsMeasure measure = rPr.isSetSpacing() ? rPr.getSpacing() : rPr.addNewSpacing();
                measure.setVal(new BigInteger(String.valueOf(spacingValue)));
            }
            return this;
        }

        /**
         * @param verticalAlign SUPERSCRIPT:上标;SUBSCRIPT:下标
         * @return
         */
        public XWPFRunBuilder verticalAlign(VerticalAlign verticalAlign) {
            ensureInit();
            if (verticalAlign != null) {
                run.setSubscript(verticalAlign);
            }
            return this;
        }

        //下划线
        public XWPFRunBuilder underLine(STUnderline.Enum underStyle, String underLineColor) {
            ensureInit();
            CTRPr rPr = getPrOfRun(run);
            CTUnderline udLine = rPr.addNewU();
            udLine.setVal(underStyle);
            udLine.setColor(underLineColor);
            return this;
        }

        //高亮
        public XWPFRunBuilder highLight(STHighlightColor.Enum highStyle) {
            ensureInit();
            CTRPr rPr = getPrOfRun(run);
            if (highStyle != null) {
                CTHighlight highLight = rPr.isSetHighlight() ? rPr.getHighlight() : rPr.addNewHighlight();
                highLight.setVal(highStyle);
            }
            return this;
        }

        public XWPFRunBuilder savePr(String rPrName) {
            ensureInit();
            if (savedRPr == null) {
                savedRPr = new HashedMap<String, CTRPr>();
            }
            savedRPr.put(rPrName, getPrOfRun(run));
            return this;
        }

        public XWPFRunBuilder samePrOf(String rPrName) {
            ensureInit();
            if (savedRPr != null && savedRPr.containsKey(rPrName)) {
                return samePrOf(savedRPr.get(rPrName));
            }
            return this;
        }

        public XWPFRunBuilder samePrOf(CTRPr rPr) {
            ensureInit();
            if (rPr != null) {
                run.getCTR().setRPr(rPr);
            }
            return this;
        }

        public XWPFRunBuilder samePrOf(XWPFRun otherRun) {
            ensureInit();
            run.getCTR().setRPr(getPrOfRun(otherRun));
            return this;
        }

        public XWPFRun build() {
            return run;
        }

        private void ensureInit() {
            if (this.run == null) {
                throw new IllegalStateException("the init method must be invoked firstly");
            }
        }
    }
  • 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

文本构建器大体上与段落构建器类似,基本上能满足大多数操作。

备注:因为只是贴出部分代码,其中有两个工具方法未给出,全部代码在github可以看到(https://github.com/jadezhang123/learning/blob/master/apple/src/main/java/own/jadezhang/learning/apple/utils/WordHolder.java

以后有时间会研究操作table,这个是重点。加油! 
测试结果

这里写图片描述

猜你喜欢

转载自blog.csdn.net/wangxintong_1992/article/details/80920835