poi读取doc列表段落前缀序号

本文介绍了如何利用Apache POI库(HWPF模块)解析DOC文件,详细阐述了读取列表段落前缀序号的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

poi doc hwpf 读取列表段落序号

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.ListData;
import org.apache.poi.hwpf.model.ListLevel;
import org.apache.poi.hwpf.model.ListTables;
import org.apache.poi.hwpf.usermodel.Paragraph;


/**
 * @author: hyl
 * @date: 2021/11/15
 **/
public class ReadDocNumber {
    /**
     * 获取列表段落的前缀编号内容,符号数字或字母,括号小数点之类的
     * 用此方法若出现第二个编号类型相同的段落列表,会直接接之前那个编号类型相同的段落列表的编号,不是从1开始。
     * 解决思路:通过列表循环时判断,如果中间出现了非段落列表类型的,就将一个特殊值传进来,一旦特殊值传进来,此方法内所有常量全部清零。
     * 已解决
     * @param paragraph 目标文本
     * @param document  目标文档
     * @return 列表编号
     */
    public static String getListNumber(Paragraph paragraph, HWPFDocument document, boolean isFirst) {
        ListTables listTables = document.getListTables();
        //如果是0为平面列表,如果为1为嵌套列表
        int lsid = paragraph.getList().getLsid();
        ListData listData = listTables.getListData(lsid);
        ListLevel[] listLevel = listData.getLevels();
        int ilvl = paragraph.getIlvl();
        ListLevel level = listLevel[ilvl];
        //所得到的numberFormat实际上对应着Microsoft的MSONFC(2.2.1.3),可以根据官网写的对应的编号类型,在这里进行组装
        //现有的为大小写字母和数字 0为十进制数字,3为大写字母,4为小写字母
        String numText = level.getNumberText();
        int numText2 = level.getNumberFormat();

        return getNumText(numText, numText2, isFirst);

    }

    //只支持6级
    //1.
    //  1.1
    //     (1)
    //        (a)
    //           1)
    //             a)
    //               A)
    //                 (A)

    private static int level_1_counter = 0;
    private static int level_2_counter = 0;
    private static int level_3_counter = 0;
    private static int level_4_counter = 0;
    private static int level_5_counter = 0;
    private static int level_6_counter = 0;
    private static int level_7_counter = 0;
    private static int level_8_counter = 0;

    public static int getLevel(String numLevelText, int numText) {
        //todo,补齐可能会出现的编号类型
        if (null == numLevelText) {
            return 0;
        }
        if ("\u0000.".equals(numLevelText)) {
            return 1;
        }
        if (numLevelText.endsWith(".\u0000")) {
            return 2;
        }
        //如果不是数字标而是字母标的numLevelText会等于4
        if ("(\u0000)".equals(numLevelText) && numText == 4) {
            return 4;
        }
        if ("(\u0000)".equals(numLevelText) && numText == 3) {
            return 7;
        }
        if ("(\u0000)".equals(numLevelText) && numText == 0) {
            return 3;
        }
        if ("\u0000)".equals(numLevelText) && numText == 4) {
            return 6;
        }
        if ("\u0000)".equals(numLevelText) && numText == 3) {
            return 8;
        }
        if ("\u0000)".equals(numLevelText) && numText == 0) {
            return 5;
        }

        return -1;
    }

    public static String getNumText(String numberFormat, int numText, boolean isFirst) {
        int level = getLevel(numberFormat, numText);
        if (level == 0) {
            return null;
        }
        if (level == -1) {
            String space = "";
            if (level_4_counter != 0) {
                space = getSpace(4);
            } else if (level_7_counter != 0) {
                space = getSpace(7);
            } else if (level_3_counter != 0) {
                space = getSpace(3);
            } else if (level_6_counter != 0) {
                space = getSpace(6);
            } else if (level_8_counter != 0) {
                space = getSpace(8);
            } else if (level_5_counter != 0) {
                space = getSpace(5);
            } else if (level_2_counter != 0) {
                space = getSpace(2);
            } else if (level_1_counter != 0) {
                space = getSpace(1);
            }
            return space + numberFormat;
        }
        if (level == 1) {
            if (isFirst) {
                level_1_counter = 0;
            }
            level_1_counter++;
            level_2_counter = 0;
            level_3_counter = 0;
            level_4_counter = 0;
            level_5_counter = 0;
            level_6_counter = 0;
            level_7_counter = 0;
            level_8_counter = 0;
            //如 1.1
            return level_1_counter + ". ";
        }
        if (level == 2) {
            if (isFirst) {
                level_2_counter = 0;
            }
            level_2_counter++;
            level_3_counter = 0;
            level_4_counter = 0;
            level_5_counter = 0;
            level_6_counter = 0;
            level_7_counter = 0;
            level_8_counter = 0;
            //如 1.1
            return getSpace(1) + String.valueOf(level_1_counter) + "." + String.valueOf(level_2_counter) + " ";
        }
        if (level == 3) {
            if (isFirst) {
                level_3_counter = 0;
            }
            level_3_counter++;
            level_4_counter = 0;
            level_5_counter = 0;
            level_6_counter = 0;
            level_7_counter = 0;
            level_8_counter = 0;
            //如 (1)
            return getSpace(2) + "(" + level_3_counter + ")";
        }
        if (level == 4) {
            if (isFirst) {
                level_4_counter = 0;
            }
            level_4_counter++;
            level_5_counter = 0;
            level_6_counter = 0;
            level_7_counter = 0;
            level_8_counter = 0;
            //如 (a)
            return getSpace(3) + "(" + (char) (96 + level_4_counter) + ")";
        }
        if (level == 5) {
            if (isFirst) {
                level_5_counter = 0;
            }
            level_5_counter++;
            level_6_counter = 0;
            level_7_counter = 0;
            level_8_counter = 0;
            //如1)
            return getSpace(4) + level_5_counter + ")";
        }
        if (level == 6) {
            if (isFirst) {
                level_6_counter = 0;
            }
            level_6_counter++;
            level_7_counter = 0;
            level_8_counter = 0;
            //如a)
            return (char) (96 + level_6_counter) + ")";
        }
        if (level == 7) {
            if (isFirst) {
                level_7_counter = 0;
            }
            level_7_counter++;
            level_8_counter = 0;
            //如A)
            return (char) (64 + level_7_counter) + ")";
        }
        if (level == 8) {
            if (isFirst) {
                level_8_counter = 0;
            }
            level_8_counter++;
            //如(A)
            return "(" + (char) (64 + level_8_counter) + ")";
        }
        return "";
    }

    private static String getSpace(int i) {
        String ret = "";
        for (int k = 0; k < i; k++) {
            ret += " ";
        }
        return ret;
    }
}


### poi-tl 列表序号使用方法 在 `poi-tl` 中,可以通过多种方式实现自定义列表序号的功能。对于特定样式的生成,比如 a), b),可以借助于 `NumberingFormat` 类来创建所需的编号格式[^1]。 #### 自定义列表序号的方法 为了设置文档内的列表项具有特殊的编号形式,如字母加括号的形式,可按照如下方式进行操作: ```java import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.data.NumberingBuilder; Map<String, Object> data = new HashMap<>(); data.put("list", NumberingBuilder.create() .addLevel().text("a)").format(NumberingScheme.LOWER_LETTER).build()); XWPFTemplate template = XWPFTemplate.compile("template.docx").render(data); FileOutputStream out = new FileOutputStream(new File("output.docx")); template.write(out); out.flush(); out.close(); ``` 上述代码片段展示了如何通过调用 `NumberingBuilder` 来构建带有特殊编号规则的列表,并将其应用到 Word 文档中。这里使用的 `LOWER_LETTER` 枚举值指定了采用小写字母作为编号的基础模式。 #### 示例说明 此示例首先导入必要的包并初始化了一个用于存储渲染数据的地图对象。接着配置了编号构造器以适应需求——即添加一层级次并设定其显示文本为 "a)" 的样式,同时选择了合适的枚举常量确保后续条目能够依次递增地展示相应字符(b), c) 等)。最后编译模板文件并将处理后的结果保存至新文件当中。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值