前言

需求:通过读取word文件来获取文档字数,便于实施业务。
一开始用的Tika来做的,由于特殊字符解析的不是很正确,又换成POI来读取也有点问题,
最后用Jacob来读取解析,达到预定的结果集。再次记录下,有不对的地方欢迎指正。

Tika的实现方式

引入依赖

<!-- https://mvnrepository.com/artifact/org.apache.tika/tika-core --><dependency><groupId>org.apache.tika</groupId><artifactId>tika-core</artifactId><version>1.20</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.tika/tika-parsers --><dependency><groupId>org.apache.tika</groupId><artifactId>tika-parsers</artifactId><version>1.20</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.tika/tika-app --><dependency><groupId>org.apache.tika</groupId><artifactId>tika-app</artifactId><version>1.20</version></dependency>

通过parseToString方法取文件内容

    public static String extract(File file) {if (file == null || !file.exists()) {throw new AppException("文件不存在");}String suffix = getSuffix(file);if (!".doc".equals(suffix) && !".docx".equals(suffix) && !".pdf".equals(suffix) && !".txt".equals(suffix)) {throw new AppException("不支持的文件格式");}Tika tika = new Tika();try {return tika.parseToString(file);} catch (IOException | TikaException e) {logger.error("cannot extract file content ", e);}return "";}public static String getSuffix(File file) {if (file.isFile()) {String name = Utils.trimilSpace(file.getName());if (name.contains(".")) {String suffix = name.substring(name.lastIndexOf("."));return suffix.toLowerCase();}}return null;}

得到文档通过Tika解析的字符串,来做统计处理
此实现方式参考 https://www.cnblogs.com/caer/p/6036408.html

public static int getMSWordsCount(String context) {int words_count = 0;// 中文单词String cn_words = context.replaceAll("[^(\\u4e00-\\u9fa5,。《》?;’‘:“”【】、)(……¥!·)]", "");int cn_words_count = cn_words.length();// 非中文单词String non_cn_words = context.replaceAll("[^(a-zA-Z0-9`\\-=\';.,/~!@#$%^&*()_+|}{\":><?\\[\\])]", " ");int non_cn_words_count = 0;String[] ss = non_cn_words.split(" ");for (String s : ss) {if (s.trim().length() != 0)non_cn_words_count++;}
//中文和非中文单词合计words_count = cn_words_count + non_cn_words_count;
//        ToolLog.d(ConstString.TAG, "汉字:" + cn_words_count + "\n\t字符:" + non_cn_words_count);return words_count;}

最终实现word字数的统计但与打开office里面显示的有出入不得在另谋途径 (若文件内没有特殊属性可以用此方法)

POI读取方式

方式1

此方式参考https://gitee.com/chunsw/codes/epjix5938htz2krgfo0ln29 兴趣的同学移步
maven依赖

 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>3.14</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.3.2</version></dependency>
import org.apache.commons.lang3.ArrayUtils;
import org.apache.poi.hwpf.extractor.WordExtractor;import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;/*** 统计字符数 字数 * @return [统计字符数,字数,运行时间]*/
public class CountDoc {static int[] wordCountNew(String doc, boolean isDebug) throws Exception {long time = System.currentTimeMillis();InputStream is = new FileInputStream(new File(doc));WordExtractor ex = new WordExtractor(is);int cnt = 0;int sumCount = 0;//统计总字符数StringBuilder builder = new StringBuilder();for (String text : ex.getParagraphText()) {
//            text = text.replaceAll("\u0007", "").replaceAll("\f", "")
//                    .replaceAll("\r", "").replaceAll("\n", "")
//                    .replaceAll("\u0015", "");if (isDebug) {text = trimAllChars(text, new char[] { '\u0007', '\f', '\b', '\u0015' });} else {text = trimAllChars(text, new char[] { '\u0007', '\f', '\b', '\u0015', '\r', '\n' });}String prefix = " TOC \\o \\u \u0014";if (text.startsWith(prefix))text = text.substring(prefix.length());
//            flag = "\u0013 EMBED Visio.Drawing.11 \u0014\u0001";
//            flag = "\u0013 EMBED Word.Document.12 \\s \u0014\u0001";int start = text.indexOf("\u0013");int end = text.indexOf("\u0014\u0001");if (start >= 0 && end > start) {text = text.replaceAll("\u0013[^\u0014\u0001]+\u0014\u0001", "");}text = text.replaceAll("\u0013[^\u0014\u0013]+\u0014", "");String flag = "\u0013 HYPERLINK";int pos = text.indexOf(flag);if (pos >= 0) {String[] arr = text.split(" \u0014");text = text.substring(0, pos) + arr[1];}if (text.length() >= 767) {// word doc格式时, 如果连续字符数数大于767个(大于等于768), 则该段落的字数不计入
//                if (text.replaceAll(" ", "").length() < text.length() - 767) { //text = text.replaceAll(" {767,}", "");
//                }}if (isDebug)builder.append(text);cnt += text.length();sumCount +=text.split(" ").length;}int t = Long.valueOf(System.currentTimeMillis() - time).intValue();if (isDebug) {System.out.println(builder.toString()); // .replaceAll("\r", "").replaceAll("\n", "")System.out.println(cnt);System.out.println(t + " ms");}return new int[] { cnt, sumCount,t };}private static String trimAllChars(String text, char[] chars) {if (text == null || text.isEmpty())return text;StringBuilder builder = new StringBuilder();for (int i = 0; i < text.length(); i++) {if (!ArrayUtils.contains(chars, text.charAt(i)))builder.append(text.charAt(i));}return builder.toString();}
}

方式2

/*** POI 读取word文件内容* @param path 文件路径* @return 文件内容字符串*/public static String readWord(String path) {String buffer = "";try {if (path.endsWith(".doc")) {InputStream is = new FileInputStream(new File(path));WordExtractor ex = new WordExtractor(is);buffer = ex.getText();ex.close();} else if (path.endsWith("docx")) {OPCPackage opcPackage = POIXMLDocument.openPackage(path);POIXMLTextExtractor extractor = new XWPFWordExtractor(opcPackage);buffer = extractor.getText();extractor.close();} else {System.out.println("此文件不是word文件!");}} catch (Exception e) {e.printStackTrace();}return buffer;}

再用此方式统计解析 https://www.cnblogs.com/caer/p/6036408.html

此上两种方式都于我的目的有些出入

Jacob方式(完全符合)

Jacob简介使用信息我就不在此阐述了,直接上实现方式
下载jar包
http://download.csdn.net/download/javashixiaofei/9696752

如上是jacob-1.17-M2.jar对应的jar包和dll文件…但是我在maven仓库中并没有发现jacob-1.17版本的.
所以如果使用maven项目的话推荐下载jacob-1.14版本的jar包和dll文件.
http://download.csdn.net/detail/ab873497717/5853741这个是dll文件,jar包文件可以去Maven仓库中去找.

重点

要说的一点就是关于到office里面宏的问题请参考下面两个链接

详细参考https://www.iteye.com/blog/men4661273-2097871

有关于 BuiltInDocumentProperties里面的属性 参考http://blog.sina.com.cn/s/blog_803215760102xjt3.html
更多宏元素属性https://docs.microsoft.com/zh-cn/office/vba/api/Word.Selection

 /*** 通过 JACOB 统计word 字数* @param path word文档所在路径*/public static Integer wordCount(String path) {ActiveXComponent wordCom = null;Dispatch wrdDocs = null;String suffix = getSuffix(path);if (!".doc".equals(suffix) && !".docx".equals(suffix) &&!".pdf".equals(suffix) && !".txt".equals(suffix)) {throw new AppException("不支持的文件格式");}try {// 建立ActiveX部件wordCom = new ActiveXComponent("Word.Application");//word应用程序不可见wordCom.setProperty("Visible", false);// 返回wrdCom.Documents的DispatchwrdDocs = wordCom.getProperty("Documents").toDispatch();//Documents表示word的所有文档窗口(word是多文档应用程序)// 调用wrdCom.Documents.Open方法打开指定的word文档,返回wordDocDispatch wordDoc = Dispatch.call(wrdDocs, "Open", path, false, true, false).toDispatch();Dispatch activeDocument  = Dispatch.get(wordCom, "ActiveDocument").toDispatch();int count = Dispatch.call(activeDocument, "BuiltInDocumentProperties",new Variant(15)).toInt();//关闭文档且不保存Dispatch.call(wordDoc, "Close", new Variant(false));return count;} catch (Exception e) {logger.warn("Failed to convert '{}'.", path);//出现此错误,应该强制杀死进程try {Runtime.getRuntime().exec("taskkill /f /im WINWORD.exe*");} catch (IOException ie) {logger.warn("failed to kill winword ", ie);}}finally {if (wordCom != null) {try {//退出进程对象wordCom.invoke("Quit", new Variant[0]);} catch (Exception e) {logger.warn("Quit word app failed", e);}wordCom = null;wrdDocs = null;}ComThread.Release();}return null;}public static String getSuffix(String fileName) {if (fileName.contains(".")) {String suffix = fileName.substring(fileName.lastIndexOf("."));return trimilSpace(suffix.toLowerCase());}throw new AppException("文件没有后缀");}

综上就是对于操作文档踩过的坑记录下,希望能起到帮助 Good luck

Poi 、Jacob 统计word文档字数实现方式相关推荐

  1. java使用jacob操作word文档

    ava使用jacob操作word文档 java调用com组件操作word使用总结(jacob) 简单描述 在此处输入简单摘要 特别声明:使用java-com技术可以完成任何VBA可以完成的office ...

  2. PHP检测字数,PHP获取word文档字数的问题

    今天碰到一个需求,是校对论文按字数来计算价格,难点就在统计word文档的字数.一开始的想法是直接用一些第三方插件包例如phpword,然后发现文档和源码中并没有相对应的方法.后来我就用phpword提 ...

  3. python统计word词频_python统计word文档中的词频

    如何将统计word文档中的词频呢?先用docx模块将word文档转变成txt格式,然后使用jieba模块进行分词,并统计词频.是不是很简单- #2020年3月10日 #Elizabeth from d ...

  4. Apache POI 密码保护只读word文档在WPS中无效

    Apache POI 密码保护只读word文档在WPS中无效 最近项目有个要求就是从系统下载的WORD文档需要进行密码保护,防止篡改.于是很自然地想到了用POI去加入只读模式然后用密码保护: XWPF ...

  5. java通过POI和jacob实现word文档的在线预览和下载

    通过POI和jacob可以实现word文档的在线预览和下载. 首先,引入以下maven依赖. <dependency><groupId>org.apache.poi</g ...

  6. Jacob处理Word文档总结以及Java操作Office2007

    使用Jacob来处理Word文档 Word或Excel程序是以一种COM组件形式存在的.如果能够在Java中调用Word的COM组件,就 能使用它的方法来获取Word文档中的文本信息.目前网上有许多提 ...

  7. Java使用POI实现导出Word文档

    POI官网链接:http://deepoove.com/poi-tl/(方便各位博友后期深入学习) 1.首先导入POM依赖包 <dependency><groupId>com. ...

  8. Jacob操作Word文档转换-XXOO

    前言 JACOB一个Java-COM中间件.通过这个组件你可以在Java应用程序中调用COM组件和Win32程序库. 一.准备 <!--添加本地的jacob.jar包--><depe ...

  9. 利用jacob操作word文档

    介绍一下jacob: jacob是在java与微软的com组件之间的桥梁,通过使用jacob自带的dll动态链接库通过jni的方式实现了在sun java平台上的程序对com调用! 下载地址: htt ...

  10. 使用JACOB操作word文档并实现打印

    由于项目需要,需要在后台对word文档中的书签进行重新填值,并进行打印.一开始已经使用Spire.Doc for Java实现了这个效果,但是这个插件是收费的,公司不想买,于是就在网上找了一段时间开源 ...

最新文章

  1. linux命令查看cpu负载,Linux下使用w命令和uptime命令查看系统负载
  2. 精品软件 推荐 ACPsoft PDF Converter 免费的多功能 PDF 转换器
  3. 使用netty实现一个类似于微信的聊天功能
  4. linux中sudo如何读取标准输入作为密码,避免每次都输入密码?
  5. 深入理解javascript原型和闭包(14)——从【自由变量】到【作用域链】
  6. 算法(4)-leetcode-explore-learn-数据结构-数组2
  7. 分类器构筑_为组织构筑基于区块链的未来做准备
  8. MSSql与MYSQL比较
  9. spark structured stream的Append模式例子
  10. 拓端tecdat:R语言用加性多元线性回归、随机森林、弹性网络模型预测鲍鱼年龄和可视化
  11. 汇编中NEG和NOT的区别(汇编初学者简单笔记)
  12. 线性代数————思维导图(上岸必备)(矩阵部分)
  13. Anaconda基本教程及常用命令(介绍、安装、基本操作、管理环境、管理包、conda和pip以及借助pqi换源)
  14. 无人机测量技术在房地一体项目中的应用
  15. An adaptive LeNet-5 model for anomaly detection(翻译)
  16. 有感于董洁为子找幼儿园因不是外籍被拒 怪自己“不争气”
  17. 基于FPGA的数字钟(四)——时钟控制模块
  18. vue设置右边距_利用页面布局设置制作工资条(不用函数)
  19. DB-Lib error message 20002, severity 9:\nAdaptive Server connection failed (xxx.xxx.com)\n 报错解决
  20. 计算机网络国培总结,国培数学研修总结

热门文章

  1. 计算机辅助设计cad实训总结,CAD上机实验报告.doc
  2. TFT-lcd液晶屏接口类型之ttl接口
  3. PCA9685与 NXP1768单片机iic通信,扩展PWM端口。已调试成功。
  4. 将谷歌浏览器设置为黑色主题背景 超酷炫黑
  5. Ubuntu 16.04安装(重装)NVIDIA驱动
  6. 16.第二十二章.信息安全管理
  7. Homography单应性矩阵原理
  8. 软件质量需要静态代码分析和动态测试
  9. matlab pi调节器,pi调节器的输入和输出_pi调节器的传递函数
  10. SPSS学习(四)单样本t检验