Word 字符数精确统计工具

复制代码
自动 fallback 全量扫描(100%准确)
java 复制代码
import org.apache.poi.ooxml.POIXMLProperties;
import org.apache.poi.xwpf.usermodel.*;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;

/**
 * Word 字符统计工具
 *
 * 功能:
 * 自动 fallback 全量扫描(100%准确)
 *
 * 适用:
 * 上传限制 / 翻译计费 / 文档校验
 */
public class WordCharCounter {

    /**
     * 根据文件路径统计
     */
    public static int count(String path) throws Exception {
        try (InputStream is = new FileInputStream(path)) {
            return count(is);
        }
    }

    /**
     * 根据流统计
     */
    public static int count(InputStream is) throws Exception {

        try (XWPFDocument doc = new XWPFDocument(is)) {

//            // ========= ① 极速模式(读取 metadata) =========
//            int fast = readFastCount(doc);
//
//            if (fast > 0) {
//                return fast;
//            }

            // ========= ② fallback 全量扫描 =========
            return slowCount(doc);
        }
    }

    /**
     * 读取 Office/WPS 预计算字数(极快)
     */
    private static int readFastCount(XWPFDocument doc) {
        try {
            POIXMLProperties.ExtendedProperties props =
                    doc.getProperties().getExtendedProperties();

            return props.getUnderlyingProperties().getCharacters();
        } catch (Exception e) {
            return 0;
        }
    }

    /**
     * 全量扫描统计(绝对准确)
     */
    private static int slowCount(XWPFDocument doc) {

        int total = 0;

        // 正文
        total += countElements(doc.getBodyElements());

        // header
        for (XWPFHeader header : doc.getHeaderList()) {
            total += countElements(header.getBodyElements());
        }

        // footer
        for (XWPFFooter footer : doc.getFooterList()) {
            total += countElements(footer.getBodyElements());
        }

        return total;
    }

    /**
     * 统计 bodyElements(段落 + 表格)
     */
    private static int countElements(List<IBodyElement> elements) {

        int total = 0;

        for (IBodyElement element : elements) {

            // 段落
            if (element instanceof XWPFParagraph) {
                total += ((XWPFParagraph) element).getText().length();
            }

            // 表格
            else if (element instanceof XWPFTable) {
                XWPFTable table = (XWPFTable) element;

                for (XWPFTableRow row : table.getRows()) {
                    for (XWPFTableCell cell : row.getTableCells()) {
                        total += cell.getText().length();
                    }
                }
            }
        }

        return total;
    }

    // ================= 测试入口 =================

    public static void main(String[] args) throws Exception {

        int count = WordCharCounter.count(
                "d:\\测试解读word内容.docx"
        );

        System.out.println("字符总数: " + count);
    }
}

相关推荐
dbkx_2913 小时前
Word域操作记录(从2开始的公式编号排版)
word
Metaphor69214 小时前
使用 Python 查找并替换 Word 文档中的文本
python·c#·word
蒋胜山15 小时前
Word 练习题(6)
经验分享·word
weixin_416660071 天前
怎么把 AI Markdown 转为 Word (.docx) 文档?
word·流程图
深念Y2 天前
AI时代办公格式的演进:PPT与Word的替代已现,Excel将走向何方?
数据库·人工智能·html·word·powerpoint·excel·markdown
家有娇妻张兔兔2 天前
Apache POI 导出 Word 踩坑实录:Word 分栏为什么做不好左右平铺
c#·word·apache·poi·分栏
努力成为大牛吧3 天前
Word/WPS 论文参考文献排版及交叉引用注意事项
word·wps
qq_283720053 天前
Python3 模块精讲|python-docx 万字实战:全自动读写 Word 文档,办公效率直接翻倍
python·自动化·word
gc_22993 天前
学习C#调用OpenXml操作word文档的基本用法(26:学习文本运行类)
word·openxml·run
蒋胜山4 天前
Word 练习题(3)
word