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

相关推荐
重生之光头强下海当程序猿8 小时前
调整word中的序号格式(缩进,起始值,序号与文字的间距等
前端·css·word
Eiceblue1 天前
C# 中如何设置 Word 文档页面?(页面大小、边距、方向自动化控制)
c#·自动化·word·visual studio
热爱生活的五柒2 天前
Word 论文里参考文献经常在修改后错乱,如何解决
word
醉酒柴柴2 天前
word创建样式以后应用于所有新文件
开发语言·学习·c#·word
珞瑜·2 天前
Windows版Word如何启用保存时自动删除个人信息
word
DS随心转插件2 天前
ChatGPT或Gemini如何生成word文档
人工智能·ai·chatgpt·word·deepseek·ds随心转
白狐_7983 天前
【疑难杂症】Word 惊现“数字 7 消失术”:特定字体 GBK 编码下的渲染陷阱排查
word
热爱生活的五柒4 天前
为什么word里面没有墨迹公式,从哪找
word
yivifu5 天前
使用VBA区分简体中文段落和繁体中文段落的方法
word·excel·vba
骆驼爱记录5 天前
Word三线表制作全攻略
自动化·word·wps·新人首发