POI 获取Word大纲级别,操作Word(2018-06-03更新)

之前的代码有误,为了避免误人子弟,2018-06-03更新。
Word中的大纲级别,可以通过getPPr().getOutlineLvl()直接提取,但需要注意,Word中段落级别,通过如下三种方式定义:
1、直接对段落进行定义;
2、对段落的样式进行定义;
3、对段落样式的基础样式进行定义。
因此,在通过“getPPr().getOutlineLvl()”提取时,需要依次在如上三处读取。
以下是自用的测试代码:

                            //判断该段落是否设置了大纲级别
                        if (para.getCTP().getPPr().getOutlineLvl() != null) {
                            // System.out.println("getCTP()");
                            System.out.println(para.getParagraphText());
                            System.out.println(para.getCTP().getPPr().getOutlineLvl().getVal());

                            //判断该段落的样式是否设置了大纲级别
                        } else if (styles.getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl() != null) {
                            // System.out.println("getStyle");
                            System.out.println(para.getParagraphText());
                            System.out.println(
                                    styles.getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl().getVal());

                            //判断该段落的样式的基础样式是否设置了大纲级别
                        } else if (styles.getStyle(styles.getStyle(para.getStyle()).getCTStyle().getBasedOn().getVal())
                                .getCTStyle().getPPr().getOutlineLvl() != null) {
                            // System.out.println("getBasedOn");
                            System.out.println(para.getParagraphText());
                            String styleName = styles.getStyle(para.getStyle()).getCTStyle().getBasedOn().getVal();
                            System.out
                                    .println(styles.getStyle(styleName).getCTStyle().getPPr().getOutlineLvl().getVal());

                            //没有设置大纲级别
                        } else {
                            // System.out.println("null");
                        }

另外:之前通过“doc.removeBodyElement()”进行拆分,需要注意的是,这里的BodyElement与XWPFParagraph不是完全等价的,即BodyElement中包括XWPFParagraph,移除时完全通过XWPFParagraph编号会错乱。判断BodyElement类型之后,强转就能够获得XWPFParagraph对象。

if (bodyElement.getElementType() == BodyElementType.PARAGRAPH) {
                    XWPFParagraph para = (XWPFParagraph) bodyElement;

原文


poi获取word文档大纲,2007以上版本,即使用XWPFDocument:

        XWPFDocument doc = new XWPFDocument(is);
        List paras = doc.getParagraphs();
        XWPFStyles styles =doc.getStyles();

        for (XWPFParagraph para : paras) {
            System.out.println(para.getStyleID());
        }

通过getStyleID或getStyle能够获取段落样式的名称;该名称可以大概猜到大纲级别;

进一步获取大纲样式,需要通过文件样式获得,通过

XWPFStyles styles =doc.getStyles();

获取文件样式,
通过

doc.getStyle()

获取文件样式CTStyles,打印出来的效果是:

<xml-fragment mc:Ignorable="w14" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml">
  <w:docDefaults>
    <w:rPrDefault>
      <w:rPr>
        <w:rFonts w:ascii="Calibri" w:cs="Times New Roman" w:eastAsia="宋体" w:hAnsi="Calibri"/>
        <w:lang w:bidi="ar-SA" w:eastAsia="zh-CN" w:val="en-US"/>
      w:rPr>
    w:rPrDefault>
    <w:pPrDefault/>
  w:docDefaults>
  <w:latentStyles w:count="267" w:defLockedState="0" w:defQFormat="0" w:defSemiHidden="1" w:defUIPriority="99" w:defUnhideWhenUsed="1">
    <w:lsdException w:name="Normal" w:semiHidden="0" w:uiPriority="0" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="heading 1" w:qFormat="1" w:semiHidden="0" w:uiPriority="9" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="heading 2" w:qFormat="1" w:semiHidden="0" w:uiPriority="9" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="heading 3" w:qFormat="1" w:semiHidden="0" w:uiPriority="9" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="heading 4" w:qFormat="1" w:semiHidden="0" w:uiPriority="9" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="heading 5" w:qFormat="1" w:semiHidden="0" w:uiPriority="0" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="heading 6" w:qFormat="1" w:semiHidden="0" w:uiPriority="0" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="heading 7" w:uiPriority="0"/>
    <w:lsdException w:name="heading 8" w:uiPriority="0"/>
    <w:lsdException w:name="heading 9" w:uiPriority="0"/>
    <w:lsdException w:name="toc 1" w:uiPriority="39"/>
    <w:lsdException w:name="toc 2" w:uiPriority="39"/>
    <w:lsdException w:name="toc 3" w:uiPriority="39"/>
    <w:lsdException w:name="toc 4" w:uiPriority="39"/>
    <w:lsdException w:name="toc 5" w:uiPriority="39"/>
    <w:lsdException w:name="toc 6" w:uiPriority="39"/>
    <w:lsdException w:name="toc 7" w:uiPriority="39"/>
    <w:lsdException w:name="toc 8" w:uiPriority="39"/>
    <w:lsdException w:name="toc 9" w:uiPriority="39"/>
    <w:lsdException w:name="caption" w:semiHidden="0" w:uiPriority="0" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Title" w:semiHidden="0" w:uiPriority="10" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Default Paragraph Font" w:uiPriority="1"/>
    <w:lsdException w:name="Body Text" w:qFormat="1"/>
    <w:lsdException w:name="Subtitle" w:semiHidden="0" w:uiPriority="11" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Strong" w:semiHidden="0" w:uiPriority="22" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Emphasis" w:semiHidden="0" w:uiPriority="20" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Table Grid" w:semiHidden="0" w:uiPriority="59" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Placeholder Text" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="No Spacing" w:semiHidden="0" w:uiPriority="1" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Light Shading" w:uiPriority="60"/>
    <w:lsdException w:name="Light List" w:uiPriority="61"/>
    <w:lsdException w:name="Light Grid" w:uiPriority="62"/>
    <w:lsdException w:name="Medium Shading 1" w:uiPriority="63"/>
    <w:lsdException w:name="Medium Shading 2" w:uiPriority="64"/>
    <w:lsdException w:name="Medium List 1" w:uiPriority="65"/>
    <w:lsdException w:name="Medium List 2" w:uiPriority="66"/>
    <w:lsdException w:name="Medium Grid 1" w:uiPriority="67"/>
    <w:lsdException w:name="Medium Grid 2" w:uiPriority="68"/>
    <w:lsdException w:name="Medium Grid 3" w:uiPriority="69"/>
    <w:lsdException w:name="Dark List" w:uiPriority="70"/>
    <w:lsdException w:name="Colorful Shading" w:uiPriority="71"/>
    <w:lsdException w:name="Colorful List" w:uiPriority="72"/>
    <w:lsdException w:name="Colorful Grid" w:uiPriority="73"/>
    <w:lsdException w:name="Light Shading Accent 1" w:uiPriority="60"/>
    <w:lsdException w:name="Light List Accent 1" w:uiPriority="61"/>
    <w:lsdException w:name="Light Grid Accent 1" w:uiPriority="62"/>
    <w:lsdException w:name="Medium Shading 1 Accent 1" w:uiPriority="63"/>
    <w:lsdException w:name="Medium Shading 2 Accent 1" w:uiPriority="64"/>
    <w:lsdException w:name="Medium List 1 Accent 1" w:uiPriority="65"/>
    <w:lsdException w:name="Revision" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="List Paragraph" w:semiHidden="0" w:uiPriority="34" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Quote" w:semiHidden="0" w:uiPriority="29" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Intense Quote" w:semiHidden="0" w:uiPriority="30" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Medium List 2 Accent 1" w:uiPriority="66"/>
    <w:lsdException w:name="Medium Grid 1 Accent 1" w:uiPriority="67"/>
    <w:lsdException w:name="Medium Grid 2 Accent 1" w:uiPriority="68"/>
    <w:lsdException w:name="Medium Grid 3 Accent 1" w:uiPriority="69"/>
    <w:lsdException w:name="Dark List Accent 1" w:uiPriority="70"/>
    <w:lsdException w:name="Colorful Shading Accent 1" w:uiPriority="71"/>
    <w:lsdException w:name="Colorful List Accent 1" w:uiPriority="72"/>
    <w:lsdException w:name="Colorful Grid Accent 1" w:uiPriority="73"/>
    <w:lsdException w:name="Light Shading Accent 2" w:uiPriority="60"/>
    <w:lsdException w:name="Light List Accent 2" w:uiPriority="61"/>
    <w:lsdException w:name="Light Grid Accent 2" w:uiPriority="62"/>
    <w:lsdException w:name="Medium Shading 1 Accent 2" w:uiPriority="63"/>
    <w:lsdException w:name="Medium Shading 2 Accent 2" w:uiPriority="64"/>
    <w:lsdException w:name="Medium List 1 Accent 2" w:uiPriority="65"/>
    <w:lsdException w:name="Medium List 2 Accent 2" w:uiPriority="66"/>
    <w:lsdException w:name="Medium Grid 1 Accent 2" w:uiPriority="67"/>
    <w:lsdException w:name="Medium Grid 2 Accent 2" w:uiPriority="68"/>
    <w:lsdException w:name="Medium Grid 3 Accent 2" w:uiPriority="69"/>
    <w:lsdException w:name="Dark List Accent 2" w:uiPriority="70"/>
    <w:lsdException w:name="Colorful Shading Accent 2" w:uiPriority="71"/>
    <w:lsdException w:name="Colorful List Accent 2" w:uiPriority="72"/>
    <w:lsdException w:name="Colorful Grid Accent 2" w:uiPriority="73"/>
    <w:lsdException w:name="Light Shading Accent 3" w:uiPriority="60"/>
    <w:lsdException w:name="Light List Accent 3" w:uiPriority="61"/>
    <w:lsdException w:name="Light Grid Accent 3" w:uiPriority="62"/>
    <w:lsdException w:name="Medium Shading 1 Accent 3" w:uiPriority="63"/>
    <w:lsdException w:name="Medium Shading 2 Accent 3" w:uiPriority="64"/>
    <w:lsdException w:name="Medium List 1 Accent 3" w:uiPriority="65"/>
    <w:lsdException w:name="Medium List 2 Accent 3" w:uiPriority="66"/>
    <w:lsdException w:name="Medium Grid 1 Accent 3" w:uiPriority="67"/>
    <w:lsdException w:name="Medium Grid 2 Accent 3" w:uiPriority="68"/>
    <w:lsdException w:name="Medium Grid 3 Accent 3" w:uiPriority="69"/>
    <w:lsdException w:name="Dark List Accent 3" w:uiPriority="70"/>
    <w:lsdException w:name="Colorful Shading Accent 3" w:uiPriority="71"/>
    <w:lsdException w:name="Colorful List Accent 3" w:uiPriority="72"/>
    <w:lsdException w:name="Colorful Grid Accent 3" w:uiPriority="73"/>
    <w:lsdException w:name="Light Shading Accent 4" w:uiPriority="60"/>
    <w:lsdException w:name="Light List Accent 4" w:uiPriority="61"/>
    <w:lsdException w:name="Light Grid Accent 4" w:uiPriority="62"/>
    <w:lsdException w:name="Medium Shading 1 Accent 4" w:uiPriority="63"/>
    <w:lsdException w:name="Medium Shading 2 Accent 4" w:uiPriority="64"/>
    <w:lsdException w:name="Medium List 1 Accent 4" w:uiPriority="65"/>
    <w:lsdException w:name="Medium List 2 Accent 4" w:uiPriority="66"/>
    <w:lsdException w:name="Medium Grid 1 Accent 4" w:uiPriority="67"/>
    <w:lsdException w:name="Medium Grid 2 Accent 4" w:uiPriority="68"/>
    <w:lsdException w:name="Medium Grid 3 Accent 4" w:uiPriority="69"/>
    <w:lsdException w:name="Dark List Accent 4" w:uiPriority="70"/>
    <w:lsdException w:name="Colorful Shading Accent 4" w:uiPriority="71"/>
    <w:lsdException w:name="Colorful List Accent 4" w:uiPriority="72"/>
    <w:lsdException w:name="Colorful Grid Accent 4" w:uiPriority="73"/>
    <w:lsdException w:name="Light Shading Accent 5" w:uiPriority="60"/>
    <w:lsdException w:name="Light List Accent 5" w:uiPriority="61"/>
    <w:lsdException w:name="Light Grid Accent 5" w:uiPriority="62"/>
    <w:lsdException w:name="Medium Shading 1 Accent 5" w:uiPriority="63"/>
    <w:lsdException w:name="Medium Shading 2 Accent 5" w:uiPriority="64"/>
    <w:lsdException w:name="Medium List 1 Accent 5" w:uiPriority="65"/>
    <w:lsdException w:name="Medium List 2 Accent 5" w:uiPriority="66"/>
    <w:lsdException w:name="Medium Grid 1 Accent 5" w:uiPriority="67"/>
    <w:lsdException w:name="Medium Grid 2 Accent 5" w:uiPriority="68"/>
    <w:lsdException w:name="Medium Grid 3 Accent 5" w:uiPriority="69"/>
    <w:lsdException w:name="Dark List Accent 5" w:uiPriority="70"/>
    <w:lsdException w:name="Colorful Shading Accent 5" w:uiPriority="71"/>
    <w:lsdException w:name="Colorful List Accent 5" w:uiPriority="72"/>
    <w:lsdException w:name="Colorful Grid Accent 5" w:uiPriority="73"/>
    <w:lsdException w:name="Light Shading Accent 6" w:uiPriority="60"/>
    <w:lsdException w:name="Light List Accent 6" w:uiPriority="61"/>
    <w:lsdException w:name="Light Grid Accent 6" w:uiPriority="62"/>
    <w:lsdException w:name="Medium Shading 1 Accent 6" w:uiPriority="63"/>
    <w:lsdException w:name="Medium Shading 2 Accent 6" w:uiPriority="64"/>
    <w:lsdException w:name="Medium List 1 Accent 6" w:uiPriority="65"/>
    <w:lsdException w:name="Medium List 2 Accent 6" w:uiPriority="66"/>
    <w:lsdException w:name="Medium Grid 1 Accent 6" w:uiPriority="67"/>
    <w:lsdException w:name="Medium Grid 2 Accent 6" w:uiPriority="68"/>
    <w:lsdException w:name="Medium Grid 3 Accent 6" w:uiPriority="69"/>
    <w:lsdException w:name="Dark List Accent 6" w:uiPriority="70"/>
    <w:lsdException w:name="Colorful Shading Accent 6" w:uiPriority="71"/>
    <w:lsdException w:name="Colorful List Accent 6" w:uiPriority="72"/>
    <w:lsdException w:name="Colorful Grid Accent 6" w:uiPriority="73"/>
    <w:lsdException w:name="Subtle Emphasis" w:semiHidden="0" w:uiPriority="19" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Intense Emphasis" w:semiHidden="0" w:uiPriority="21" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Subtle Reference" w:semiHidden="0" w:uiPriority="31" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Intense Reference" w:semiHidden="0" w:uiPriority="32" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Book Title" w:semiHidden="0" w:uiPriority="33" w:unhideWhenUsed="0"/>
    <w:lsdException w:name="Bibliography" w:uiPriority="37"/>
    <w:lsdException w:name="TOC Heading" w:qFormat="1" w:uiPriority="39"/>
  w:latentStyles>
  <w:style w:default="1" w:styleId="a0" w:type="paragraph">
    <w:name w:val="Normal"/>
    <w:rsid w:val="00B926D7"/>
    <w:pPr>
      <w:widowControl w:val="0"/>
      <w:jc w:val="both"/>
    w:pPr>
    <w:rPr>
      <w:rFonts w:ascii="Arial" w:hAnsi="Arial"/>
      <w:kern w:val="2"/>
      <w:sz w:val="21"/>
      <w:szCs w:val="22"/>
    w:rPr>
  w:style>
  <w:style w:styleId="1" w:type="paragraph">
    <w:name w:val="heading 1"/>
    <w:aliases w:val="1级标题"/>
    <w:basedOn w:val="a0"/>
    <w:next w:val="a1"/>
    <w:link w:val="1Char"/>
    <w:uiPriority w:val="9"/>
    <w:qFormat/>
    <w:rsid w:val="00FD4CB4"/>
    <w:pPr>
      <w:keepNext/>
      <w:numPr>
        <w:numId w:val="1"/>
      w:numPr>
      <w:spacing w:after="60" w:before="60" w:line="360" w:lineRule="auto"/>
      <w:outlineLvl w:val="0"/>
    w:pPr>
    <w:rPr>
      <w:b/>
      <w:bCs/>
      <w:kern w:val="44"/>
      <w:sz w:val="32"/>
      <w:szCs w:val="44"/>
    w:rPr>
  w:style>

大概就是文件样式xml格式吧?我猜的。
通过这个就可以获取样式的大纲级别,就是这一段:

"1" w:type="paragraph">
    val="heading 1"/>

“heading 1”应该是段落的大纲级别1级。
通过:

String strStyle=para.getStyleID();
styles.getStyle(strStyle).getCTStyle().getName().getVal()

以上是获取word章节目录方法,下面说明word拆分
word的拆分没有找到类似于Word vba/vb/c# 那种copy,saveas那种方法,使用

doc.setParagraph(paragraph, pos);

以及类似的run方法,添加的都是纯文本,所以选择了一种略显愚蠢的方法,之前复制全文,再进行删减,就不需要考虑样式问题了

doc.removeBodyElement(i);

poi好像没有提供移除段落的方法,即使删除了段落的所有run,貌似还是有一个空白段落,所以使用移除bodyElement的方式。


对于word文件分割,还有的问题是拆分后,章节的自动多级列表也会变化,在Word API中提供了直接将多级列表转换为普通文本的方法,但是POI貌似没有,或者我没找到,所以同意采用笨办法。
先移除样式中的多级列表,然后手动添加,相关代码:

//移除多级列表
doc.getStyles().getStyle("1").getCTStyle().getPPr().unsetNumPr();

//在段首添加编号
XWPFRun run = paras.get(7).insertNewRun(0);
run.setText("10086:");

以上提供的方式不代表最好的,只是本人现阶段找到的解决方案而已
完整核心代码如下,不嫌难看的话讲究用用:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFStyles;

public class lik1 {

    public static void main(String[] args) {

        String path = "F:\\testWord\\a1.docx";

        InputStream is = null;
        try {
            is = new FileInputStream(path);
        } catch (FileNotFoundException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }       

        XWPFDocument doc=null;
        try {
            doc = new XWPFDocument(is);
        } catch (IOException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
        //获取段落
        List paras=doc.getParagraphs();
        //获取doc样式
        XWPFStyles styles=doc.getStyles();

        int j=0;
        for (XWPFParagraph para : paras){

            ArrayList al=new ArrayList();

            try {
                al.add(styles.getStyle(para.getStyle()).getCTStyle().getName().getVal());
            } catch (Exception e) {
                // TODO: handle exception
            }
            al.add(para.getParagraphText());
            System.out.println(j++ + ":" + al);

        }

        for (int i=16;i>11;i--){
            doc.removeBodyElement(i);
        }

        paras.get(7).setStyle(paras.get(1).getStyle());
        styles.getStyle(paras.get(1).getStyle()).getCTStyle().getPPr().unsetNumPr();

        XWPFRun run=paras.get(7).insertNewRun(0);
        run.setText("10086");

        OutputStream out=null;
        try {
            out=new FileOutputStream("F:\\testWord\\a2.docx");

        } catch (FileNotFoundException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
        try {
            doc.write(out);
        } catch (IOException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }


        System.out.println("over");

    }

}

你可能感兴趣的:(poi,word,多级列表,拆分,章节大纲)