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);
    }
}

相关推荐
骆驼爱记录4 小时前
Word题注编号间距调整4种方法
自动化·word·excel·wps·新人首发
AAA_搬砖达人小郝5 小时前
Markdown 一键生成完美 Word(.docx) + PDF 的完整实战方案(JDK 8 环境亲测可用)
pdf·word
DS随心转插件1 天前
Gemini怎么生成word
人工智能·word·ds随心转
缺点内向1 天前
在 C# 中为 Word 段落添加制表位:使用 Spire.Doc for .NET 实现高效排版
开发语言·c#·自动化·word·.net
星月前端1 天前
springboot中使用LibreOffice实现word转pdf(还原程度很高,可以配置线程并发!)
spring boot·pdf·word
qq_171520351 天前
linux服务器springboot(docker)项目word转pdf中文乱码
linux·spring boot·docker·pdf·word
weixin_416660072 天前
AI 生成复杂公式在 Word 中乱码的原因与解决方案
ai·word·数学公式
缺点内向2 天前
Word 自动化处理:如何用 C# 让指定段落“隐身”?
开发语言·c#·自动化·word·.net
。puppy3 天前
SQL 注入整理
数据库·sql·word