最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

利用Java實現(xiàn)Word文檔自動編號提取的方法詳解

 更新時間:2025年09月26日 10:20:31   作者:瘋癲的老碼農(nóng)  
文章介紹如何用Java從Word試卷中提取自動編號,通過創(chuàng)建NumberingContext類識別中文、阿拉伯數(shù)字及字母等不同編號格式,并實現(xiàn)getParagraphNumbering方法完成結(jié)構(gòu)化轉(zhuǎn)換,解決了傳統(tǒng)方法無法解析編號的問題,感興趣的小伙伴可以參考閱讀下

一、背景

因業(yè)務需求,目前正在實現(xiàn)一項需求,即將一份試卷的內(nèi)容提取出來,由非結(jié)構(gòu)化到結(jié)構(gòu)化的轉(zhuǎn)換。在試卷解析的時候發(fā)現(xiàn)存在大綱目錄中帶有自動編號的格式,按照傳統(tǒng)的方式?jīng)]有解析出來,花了一番功夫,最終還是搞定了,于是寫下來分享給大家。

二、概述

從一份word格式的試卷中,用java從XWPFParagraph中先判斷是否有編號,如果有再提取自動編號,自動編號還是會區(qū)分不同類型的,如中文的一、二、三等,阿拉伯數(shù)字的1、2、3等,或者是字母a、b、c等。

三、正文

1、需要先實現(xiàn)一個自動編號上下文的class:

NumberingContext里面注冊了不同格式的編號,如大寫字母編號、小寫字母編號、中文編號等,具體可以看代碼:

 
public class NumberingContext {
    private final Map<String, List<Integer>> numberingStates = new HashMap<>();
    // 編號格式映射(可以擴展更多格式)
    public static final Map<String, NumberFormatter> FORMATTERS = new HashMap<>();
 
    static {
        FORMATTERS.put("decimal", new DecimalFormatter());
        FORMATTERS.put("lowerLetter", new LowerLetterFormatter());
        FORMATTERS.put("upperLetter", new UpperLetterFormatter()); // 新增
        FORMATTERS.put("upperRoman", new UpperRomanFormatter());
        FORMATTERS.put("chineseCounting", new ChineseCountingFormatter());
    }
 
    public String resolveNumberText(String numIdKey, int ilvl, String format, String textTemplate) {
        List<Integer> counters = numberingStates.computeIfAbsent(numIdKey, k -> new ArrayList<>());
 
        // 確保層級計數(shù)器足夠長
        while (counters.size() <= ilvl) {
            counters.add(0);
        }
 
        // 更新當前層級計數(shù)器,并清空下級
        counters.set(ilvl, counters.get(ilvl) + 1);
        for (int i = ilvl + 1; i < counters.size(); i++) {
            counters.set(i, 0);
        }
 
        // 獲取格式化器
        NumberFormatter formatter = FORMATTERS.get(format);
        if (formatter == null) {
            formatter = new DecimalFormatter();
        }
 
        // 替換模板中的占位符
        String result = textTemplate;
        for (int i = 0; i <= ilvl; i++) {
            String placeholder = "%" + (i + 1);
            if (i < counters.size()) {
                String replacement = formatter.format(counters.get(i));
                result = result.replace(placeholder, replacement);
            }
        }
 
        return result;
    }
}

2、不同類型的編號格式

1、DecimalFormatter

public class DecimalFormatter implements NumberFormatter {
    @Override
    public String format(int number) {
        return String.valueOf(number);
    }
}

2、LowerLetterFormatter

public class LowerLetterFormatter implements NumberFormatter {
    @Override
    public String format(int number) {
        return String.valueOf((char) ('a' + number - 1));
    }
}

3、UpperLetterFormatter

public class UpperLetterFormatter  implements NumberFormatter {
    @Override
    public String format(int number) {
        if (number < 1 || number > 26) {
            throw new IllegalArgumentException("upperLetter 格式僅支持 1-26");
        }
        return String.valueOf((char) ('A' + number - 1));
    }
}

3、接下來就是核心邏輯:

這個getParagraphNumbering方法就是可以從XWPFParagraph

提取自動的編號

public static String getParagraphNumbering(NumberingContext numberingContext, XWPFParagraph paragraph) {
        try {
            if (paragraph.getNumID() == null) {
                //"無編號";
                return "";
            }
 
            BigInteger numId = paragraph.getNumID();
            BigInteger ilvl = paragraph.getNumIlvl() != null ? paragraph.getNumIlvl() : new BigInteger("0");
 
            // 使用numId和文檔信息創(chuàng)建唯一鍵
            String numIdKey = numId.toString();
 
            XWPFNumbering numbering = paragraph.getDocument().getNumbering();
            if (numbering == null) {
                //"無編號定義";
                return "";
            }
 
            XWPFNum num = numbering.getNum(numId);
            if (num == null) {
                //"編號定義不存在";
                return "";
            }
 
            BigInteger abstractNumId = num.getCTNum().getAbstractNumId().getVal();
            for (XWPFAbstractNum abstractNum : numbering.getAbstractNums()) {
                if (abstractNum.getCTAbstractNum().getAbstractNumId().equals(abstractNumId)) {
                    CTAbstractNum ctAbstractNum = abstractNum.getCTAbstractNum();
                    CTLvl ctLvl = ctAbstractNum.getLvlArray(ilvl.intValue());
                    if (ctLvl != null && ctLvl.getNumFmt() != null && ctLvl.getLvlText() != null) {
                        String format = ctLvl.getNumFmt().getVal().toString();
                        String text = ctLvl.getLvlText().getVal();
 
                        return numberingContext.resolveNumberText(
                                numIdKey, ilvl.intValue(), format, text);
                    }
                }
            }
 
            //"編號層級不存在或定義不完整";
            return "";
        } catch (Exception e) {
            //"解析編號時出錯";
            return "";
        }
    }

到此這篇關(guān)于利用Java實現(xiàn)Word文檔自動編號提取的方法詳解的文章就介紹到這了,更多相關(guān)Java Word文檔自動編號提取內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • nacos服務無法注冊到nacos服務中心問題及解決

    nacos服務無法注冊到nacos服務中心問題及解決

    本文詳細描述了在Linux服務器上使用Tomcat啟動Java程序時,服務無法注冊到Nacos的排查過程,通過一系列排查步驟,發(fā)現(xiàn)問題出在Tomcat的啟動機制上,導致無法自動觸發(fā)服務注冊事件,最終,通過實現(xiàn)`ApplicationRunner`接口,手動觸發(fā)服務注冊事件,解決了問題
    2025-11-11
  • 解決Maven項目中 Invalid bound statement 無效的綁定問題

    解決Maven項目中 Invalid bound statement 無效的綁定問題

    這篇文章主要介紹了解決Maven項目中 Invalid bound statement 無效的綁定問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • java中List對象列表實現(xiàn)去重或取出及排序的方法

    java中List對象列表實現(xiàn)去重或取出及排序的方法

    這篇文章主要介紹了關(guān)于java中List對象列表實現(xiàn)去重或取出以及排序的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面跟著小編來一起學習學習吧。
    2017-08-08
  • MybatisPlus:使用SQL保留字(關(guān)鍵字)的操作

    MybatisPlus:使用SQL保留字(關(guān)鍵字)的操作

    這篇文章主要介紹了MybatisPlus:使用SQL保留字(關(guān)鍵字)的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • SpringBoot外部化配置使用Plus版的方法示例

    SpringBoot外部化配置使用Plus版的方法示例

    這篇文章主要介紹了SpringBoot外部化配置使用Plus版的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • JAVA Netty實現(xiàn)聊天室+私聊功能的示例代碼

    JAVA Netty實現(xiàn)聊天室+私聊功能的示例代碼

    這篇文章主要介紹了JAVA Netty實現(xiàn)聊天室+私聊功能的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • java迷宮算法的理解(遞歸分割,遞歸回溯,深搜,廣搜)

    java迷宮算法的理解(遞歸分割,遞歸回溯,深搜,廣搜)

    本文主要使用的算法(自動生成地圖:遞歸分割法、遞歸回溯法;尋找路徑:深度優(yōu)先、廣度優(yōu)先算法),非常具有實用價值,需要的朋友可以參考下
    2021-06-06
  • MYSQL批量插入數(shù)據(jù)的實現(xiàn)代碼

    MYSQL批量插入數(shù)據(jù)的實現(xiàn)代碼

    非常的實現(xiàn)原理,代碼較多,建議大家仔細看看。
    2008-10-10
  • 搭建JavaWeb服務器步驟詳解

    搭建JavaWeb服務器步驟詳解

    本篇文章主要給大家詳細分享了搭建JavaWeb服務器的詳細步驟以及用到的代碼,對此有需要的朋友可以跟著學習下。
    2018-02-02
  • SpringBoot 項目添加 MDC 日志鏈路追蹤的執(zhí)行流程

    SpringBoot 項目添加 MDC 日志鏈路追蹤的執(zhí)行流程

    日志鏈路追蹤就是將一個標志跨線程進行傳遞,在一般的小項目中也就是在你新起一個線程的時候,或者使用線程池執(zhí)行任務的時候會用到,比如追蹤一個用戶請求的完整執(zhí)行流程,本文給大家介紹SpringBoot MDC 日志鏈路追蹤的代碼,感興趣的朋友一起看看吧
    2021-06-06

最新評論

灵石县| 大姚县| 同心县| 陕西省| 蒙山县| 交口县| 双牌县| 宁强县| 韶关市| 石嘴山市| 巴马| 获嘉县| 镇坪县| 崇义县| 寿宁县| 乌恰县| 丹东市| 磐安县| 德格县| 开江县| 临潭县| 姜堰市| 莆田市| 夏津县| 绥芬河市| 淄博市| 定陶县| 襄城县| 东宁县| 长治市| 扶风县| 琼结县| 石阡县| 新乡县| 屏东县| 峨眉山市| 顺昌县| 乌兰察布市| 内丘县| 达州市| 武川县|