POI 操作word

来源:互联网 发布:航线地面站软件 编辑:程序博客网 时间:2024/05/10 04:22

关于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");            }        }    }

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

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

如果有一段段落的属性与之前段落相同,你可以在链尾调用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");            }        }    }

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

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

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

这里写图片描述

0 0