文档章节

使用Java基于数据流直接抽取word文本

 脚本爱好者
发布于 2012/06/25 11:42
字数 527
阅读 221
收藏 1

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

如下代码是直接基于数据流进行文本抽取,支持word97-word2003版本,之后的版本实际都是xml,抽取文本非常简单,因此在此处不再说明,代码仅供研究学习使用,禁止用于商业用途。


public class WordExtractor {
   
    public static StringBuilder logBytes = new StringBuilder();
   
    public static String bytesToString(byte[] ogiBytes, int start, int length, int fc)
    {
        StringBuilder content = new StringBuilder();
        byte[] bytes = new byte[length];
        System.arraycopy(ogiBytes, start, bytes, 0, length);
        if(fc == 0)
        {
            for(int i=0;i<bytes.length;i++)
            {
                if(i == bytes.length - 1)
                {
                    return content.toString();
                }
               
                String a = Integer.toHexString(bytes[i+1] & 0xFF);
                String b = Integer.toHexString(bytes[i] & 0xFF);
                if(a.length() == 1)
                {
                    a = "0"+ a;
                }
               
                if(b.length() == 1)
                {
                    b = "0"+ b;
                }
               
                String hexStr = a + b;
                int ch = Integer.valueOf(hexStr, 16);
                content.append( (char)ch );
                i++;
            }
        }
        else
        {
            for(int i=0;i<bytes.length;i++)
            {
                int ch = bytes[i] & 0xFF;
                content.append( (char)ch );
            }
        }
       
        return content.toString();
    }
   
    public static void bytesToString(byte[] ogiBytes, StringBuilder content, int start, int length, int fc)
    {
        content.append( bytesToString(ogiBytes, start, length, fc) );
    }
   
    public static void printLogBytes(List<Byte> legaled) throws Exception
    {
        logBytes = new StringBuilder();
       
        logBytes.append(" ========================================================");
        for(int a=0;a<legaled.size();a++)
        {
            if(a % 16 == 0)
            {
                logBytes.append(" ");
            }
            logBytes.append(Integer.toHexString(legaled.get(a) & 0xFF) +" ");
        }
        logBytes.append(" ========================================================");
       
        FileUtil.writeAscFile("E:ytes.txt", logBytes.toString());
    }
   
    public static int getOneTable(byte[] ogiBytes, Stream stream, int dirSect1)
    {
        for(int i=0;i<8;i++)
        {
            int offsetEntry = (dirSect1 + 1)*512 + i*128;
            StringBuilder content = new StringBuilder();
            bytesToString(ogiBytes, content, offsetEntry, 64, 0);
            if(content.toString().indexOf("1Table") > -1)
            {
                return offsetEntry;
            }
        }
       
        return 0;
    }
   
    public static void main(String[] args) throws Exception
    {
        byte[] ogiBytes = FileUtil.readBinFile("D: oolsoletest est-old.doc");
       
        System.out.println("Total bytes: "+ ogiBytes.length);
        if(
                ogiBytes.length < 8         ||
                (ogiBytes[0] & 0xFF) != 208 ||
                (ogiBytes[1] & 0xFF) != 207 ||
                (ogiBytes[2] & 0xFF) != 17     ||
                (ogiBytes[3] & 0xFF) != 224 ||
                (ogiBytes[4] & 0xFF) != 161 ||
                (ogiBytes[5] & 0xFF) != 177 ||
                (ogiBytes[6] & 0xFF) != 26     ||
                (ogiBytes[7] & 0xFF) != 225
        ){
            System.out.println("Not the doc file!");
            return;
        }
       
        StringBuilder content = new StringBuilder();
       
        Stream stream = new Stream(ogiBytes);
        int[] offset = new int[1];
       
        offset[0] = 48;
        int dirSect1 = stream.getInteger(offset);
        int oneTable = getOneTable(ogiBytes, stream, dirSect1);
       
        offset[0] = oneTable + 116;
        int startSect = stream.getInteger(offset);
        int tableStream = (startSect + 1)*512;
       
        offset[0] = 930;
        int fcClx = stream.getInteger(offset);
        if(fcClx == -1)
        {
            System.out.println("This version of doc can not be parsed!");
            return;
        }
       
        int offsetClx = tableStream + fcClx;
       
        offset[0] = offsetClx + 1;
        int lcb = stream.getInteger(offset);
      
        int countPcd = (lcb - 4)/12;
        int countCp = (lcb - countPcd*8)/4;
        int offsetPlcpcd = offsetClx + 5;
      
        for(int i=0;i<countPcd;i++)
        {
            int offsetPcd = offsetPlcpcd + countCp*4 + i*8;
           
            offset[0] = offsetPcd + 2;
            int start = stream.getInteger(offset);
            int fc = start >> 30;
            start = (start << 2) >> 2;
      
            offset[0] = offsetPlcpcd + i*4;
            int cpPre = stream.getInteger(offset);
            int cpNext = stream.getInteger(offset);
            int length = cpNext - cpPre -1;
            if(fc == 0)
            {
                length *= 2;
            }
            else
            {
                start = start/2;
            }
           
            start += 512;
            bytesToString(ogiBytes, content, start, length, fc);
       
            System.out.println(start +", "+ length);
        }
       
        FileUtil.writeAscFile("E:output.txt", content.toString(), false);
       
        System.out.println("Done!");
       
    }
}

参考资料:
http://blog.csdn.net/hu0406/article/details/3157192
http://msdn.microsoft.com/zh-cn/library/gg615596.aspx

本文转载自:http://www.xiaomeiti.com

粉丝 1
博文 2
码字总数 0
作品 0
东城
程序员
私信 提问
Eclipse快捷键大全(转载)

Ctrl+1 快速修复(最经典的快捷键,就不用多说了) Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加) Ctrl+Alt+↑ 复制当前行到上一行(复制增加) Alt+↓ 当前行和下面一行交互位置...

JavaGG
2009/03/12
265
0
Java语言学习(十):输入/输出

Java中,I/O操作代表着输入、输出,Java所有的I/O机制都是基于数据流进行输入输出。java.io类包提供了很多的输入输出处理功能方法,大家可以参考下JDK文档中关于I/O的一些处理方法:JDK在线中...

海岸线的曙光
2018/07/18
16
0
ecplise常用的快捷键(汇总)

不多说,直接奉上: Ctrl+1 快速修复(最经典的快捷键,就不用多说了) Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加) Ctrl+Alt+↑ 复制当前行到上一行(复制增加) Alt+↓ 当前行和...

爱幻想的螃蟹
2014/08/06
145
0
Eclipse常用快捷键一页纸(草稿)

知猪侠_DC 搜集整理自互联网,众人拾柴火焰高,感谢网友的无私分享。 Ctrl+1 快速修复 Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加) Ctrl+Alt+↑ 复制当前行到上一行(复制增...

知猪侠_DC
03/20
0
0
Eclipse平台快捷键,开发必备!

学习Android开发,eclipse的使用是少不了的,今天找了一些eclipse的快捷键跟大家分享一下,后续还会有更多资料和大家分享,呵呵,一起努力吧! Ctrl+1 快速修复(最经典的快捷键,就不用多说了...

铂金小猪
2011/08/17
138
0

没有更多内容

加载失败,请刷新页面

加载更多

聊聊rocketmq producer的batch

序 本文主要研究一下rocketmq producer的batch batch rocketmq-client-4.6.0-sources.jar!/org/apache/rocketmq/client/producer/DefaultMQProducer.java public class DefaultMQProducer ex......

go4it
昨天
4
0
Delphi中的延时

开发过程中经常会需要使用到延时功能,Delphi中有不少实现延时的方法,网上已有不少文章做过说明和分析,但本着实践出真知的态度,还是亲自动手研究一番心里比较踏实。 常用的延时方法 Slee...

天朝八阿哥
昨天
4
0
001-Consul

Consul安装(单节点) mkdir -p /data/consulcd /data/consulwget https://releases.hashicorp.com/consul/1.6.2/consul_1.6.2_linux_amd64.zipunzip consul_1.6.2_linux_amd64.zip复制c......

伟大源于勇敢的开始
昨天
4
0
nginx + frp 搭建内网穿透

上一个项目是开发微信公众号,由于微信的各种烦人操作,只能到处找内网映射工具 ngrok也用过,花生壳也用过 都不怎么稳定,无意间听说了frp,本着一颗折腾的心搭建了一下,结果发现很不错,就...

lineasy
昨天
7
0
构建CRD工程 - 程序员学点xx 43 k8s

Kubernetes -3- <!--more--> <center>这是yann的第98篇分享</center> [TOC] 本日状态: 帮同事排了一天bug。 Kubernetes -3- <!--more--> 这是yann的第98篇分享 第 1 部分 承前 昨天用视屏的方......

tmp4
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部