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

标签: Java资料 | 发表时间:2012-05-29 08:00 | 作者:Administrator
出处:http://www.scriptlover.com
如下代码是直接基于数据流进行文本抽取,支持excel97-excel2003版本,之后的版本实际都是xml,抽取文本非常简单,因此在此处不再说明,代码仅供研究学习使用,禁止用于商业用途。


public class ExcelExtractor {
   
    public static StringBuilder logBytes = new StringBuilder();
   
    public static String bytesToString(byte[] ogiBytes, int start, int length, int fc, int[] offset, int fExtSt)
    {
        StringBuilder content = new StringBuilder();
        int streamLength = start+length;
        if(fc == 0)
        {
            for(int i=start;i<streamLength;i++)
            {
                if(i == streamLength - 1)
                {
                    return content.toString();
                }
               
                String a = Integer.toHexString(ogiBytes[i+1] & 0xFF);
                String b = Integer.toHexString(ogiBytes[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=start;i<streamLength;i++)
            {
                int ch = ogiBytes[i] & 0xFF;
                if(fExtSt == 0)
                {
                    if(ch < 32 || ch > 126 || (ch > 57 && ch < 64))
                    {
                        streamLength++;
                        if(offset != null && offset.length > 0)
                        {
                            offset[0]++;
                        }
                        continue;
                    }
                }
                content.append( (char)ch );
            }
        }
       
        return content.toString();
    }
   
    public static void bytesToString(byte[] ogiBytes, StringBuilder content, int start, int length, int fc, int[] offset)
    {
        content.append( bytesToString(ogiBytes, start, length, fc, offset, 1) );
       
    }
   
    public static void printLogBytes(List<Byte> legaled) throws Exception
    {
        logBytes = new StringBuilder();
       
        logBytes.append("\n========================================================");
        for(int a=0;a<legaled.size();a++)
        {
            if(a % 16 == 0)
            {
                logBytes.append("\n");
            }
            logBytes.append(Integer.toHexString(legaled.get(a) & 0xFF) +" ");
        }
        logBytes.append("\n========================================================");
       
        FileUtil.writeAscFile("E:\\bytes.txt", logBytes.toString());
    }
   
    public static int getWorkBook(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, null);
            if(content.toString().indexOf("Workbook") > -1)
            {
                return offsetEntry;
            }
        }
       
        return 0;
    }
   
    public static void processBoundSheet(Stream stream, int lbPlyPos, int docStart, int docLength, StringBuilder content, String[] sst)
    {
        if(sst == null || sst.length == 0)
        {
            return;
        }
       
        int[] offset = new int[1];
       
        /**
         * skip the BOF record
         * */
        offset[0] = lbPlyPos + 20;
        short type = stream.getShort(offset);
        if(type != 523)
        {
            System.out.println("Index record not found!");
            return ;
        }
       
        int length = stream.getShort(offset);
        offset[0] += length;
       
        int streamLength = docStart+docLength;
        while(offset[0] < streamLength)
        {
            type = stream.getShort(offset);
            length = stream.getShort(offset);
            if(type == 253)
            {
                offset[0] += 6;
                int sstIndex = stream.getInteger(offset);
                if(sstIndex < sst.length)
                {
                    content.append( sst[sstIndex] );
                }
            }
            else
            {
                offset[0] += length;
            }
        }
    }
   
    public static String[] getSST(Stream stream, int docStart, int docLength)
    {
        int[] offset = new int[1];
        offset[0] = docStart;
        int streamLength = docStart+docLength;
       
        String[] sst = null;
        while(offset[0] < streamLength)
        {
            short type = stream.getShort(offset);
            short length = stream.getShort(offset);
           
            switch(type)
            {
            case 252:
                offset[0] += 4;
                int sstLength = stream.getInteger(offset);
                sst = new String[sstLength];
                for(int i=0;i<sstLength;i++)
                {
                    int cch = stream.getShort(offset);
                    byte flags = stream.getByte(offset);
                    int fHightByte = flags & 1;
                    int fExtSt = flags >> 2;
                    int fRichSt = flags >> 3;
                    int rgRun = 0;
                   
                    int fc = fHightByte != 0 ? 0 : 1;
                    cch = fc == 0 ? cch*2 : cch;
                   
                    if(fRichSt != 0)
                    {
                        short cRun = stream.getShort(offset);
                        rgRun = cRun*4;
                    }
                   
                    if(fExtSt != 0)
                    {
                        offset[0] += 4;
                    }
                    sst[i] = bytesToString(stream.getBytes(), offset[0], cch, fc, offset, fExtSt);
                    if(fExtSt != 0)
                    {
                        offset[0] += 14 + 2;
                    }
                   
                    offset[0] += (cch + rgRun);
                }
               
                break;
            default:
                offset[0] += length;
                break;
            }
           
        }
       
        return sst;
    }
   
    public static void main(String[] args) throws Exception
    {
        byte[] ogiBytes = FileUtil.readBinFile("D:\\tools\\oletest\\2.xls");
       
        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;
        }
       
        Stream stream = new Stream(ogiBytes);
        int[] offset = new int[1];
       
        offset[0] = 48;
        int dirSect1 = stream.getInteger(offset);
        int workbook = getWorkBook(ogiBytes, stream, dirSect1);
        if(workbook <= 0)
        {
            System.out.println("This version of xls can not be parsed!");
            return;
        }
       
        offset[0] = workbook + 116;
        int startSect = stream.getInteger(offset);
        int docStart = (startSect + 1)*512;
        int docLength = stream.getInteger(offset);
       
        StringBuilder content = new StringBuilder();
       
        offset[0] = docStart;
        int streamLength = docStart+docLength;
        String[] sst = getSST(stream, docStart, docLength);
        while(offset[0] < streamLength)
        {
            short type = stream.getShort(offset);
            short length = stream.getShort(offset);
           
            switch(type)
            {
            case 133:
                int lbPlyPos = stream.getInteger(offset) + docStart;
                System.out.println("BoundSheet found! "+ lbPlyPos);
                processBoundSheet(stream, lbPlyPos, docStart, docLength, content, sst);
               
                offset[0] += (length - 4);
                break;
            default:
                offset[0] += length;
                break;
            }
           
        }
       
        FileUtil.writeAscFile("E:\\output.txt", content.toString(), false);
       
        System.out.println("Done!");
       
    }
}

相关 [java 数据 excel] 推荐:

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

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

Java程序连接数据库查询再导出Excel中

- - Java - 编程语言 - ITeye博客
     * 到处Excel文件的Action.         // 调用导出方法.      * @param col 所要导出对象集合.         FileOutputStream out = new FileOutputStream("d://"+"导出excel数据"+System.currentTimeMillis() + ".xls");.

Excel 数据分析

- - ITeye博客
用Excel做数据分析——直方图. 已有 0 人发表留言,猛击->> 这里<<-参与讨论. —软件人才免语言低担保 赴美带薪读研.

java导出excel超出65536条处理

- - Java - 编程语言 - ITeye博客
poi包导出excel超出65536报错:. 解决办法1:XSS替换HSS. 支持office2007,可以超过65536行,当数据比较多的时候,会报内存溢出的错误,解决办法看:http://blog.csdn.net/wula0010/article/details/5329817,调整jvm的堆栈大小设置.

excel数据导入mysql数据库

- - 互联网 - ITeye博客
1、excel另存为txt.       选中将要导出的数据列,然后另存为选择其它格式=>文本文件(制表符分割). E:\项目\fblike\game_code_san.txt. 2、txt导入到mysql数据库. load data infile 'E:\\项目\\fblike\\game_code_san.txt' into table game_code_san(code).

EXCEL数据处理、分析神器汇总

- 杨振华 - 小蚊子乐园
1、谁说菜鸟不会数据分析--数据下载. 微盘下载   Dbank网盘下载  新浪共享资料下载. 2、EXCEL文本标签添加神器:JWalk Chart Tools. 微盘下载   Dbank网盘下载    新浪共享资料下载  使用操作指引. 3、EXCEL文件拆分、合并、汇总神器:常用工具6.5版(彭希仁).

利用kettle组件导入excel文件到数据库

- - CSDN博客数据库推荐文章
利用kettle组件导入excel文件到数据库.        把excel文件内容导入到目标表中;然后用java调用kettle的转换. excel文件的内容只有两列,示例如下:.        数据库表的结构如下:. 使用oracle函数解决上图黄色行的字段:两个uuid和两个系统日期;. 需要生成uuid,这个在oracle中可以利用SYS_UUID()函数实现;.

数据库管理移植工具(EXCEL相关) ver 20140427

- - ITeye博客
 DBTOOLS支持ORACLE,MYSQL,SQLSERVER,POSTGRE,DB2数据库相互转换功能. 将数据库中的表结构和数据保存到EXCEL中. 将EXCEL中的数据,同步到数据库中. 当表结构发生变化时,数据不会丢失. 程序执行前后,表中的数据发生了哪些变化. 根据EXCEL中的表结构,生成建表语句SQL文.

如何在EXCEL中使用SQL进行数据处理与分析

- 蒋冰 - 小蚊子乐园
如无法查看动态演示,需要点击图片,再点击图片下的“查看原图”即可. 方法一:利用Microsoft Query使用SQL语句. 方法二:利用现有链接--导入数据--连接属性--文本命令方式使用SQL语句. 《谁说菜鸟不会数据分析》--基于通用的Excel工具,像小说一样通俗易懂的数据分析教程,现在  卓越   京东   当当   China-pub 上可订购,敬请各位数据分析爱好者关注.

Penguins DbTools数据库管理移植差分工具(EXCEL相关) ver 20150201

- - Oracle - 数据库 - ITeye博客
非凡软件站下载地址 http://www.crsky.com/soft/69885.html. DBTOOLS支持ORACLE,MYSQL,SQLSERVER,POSTGRE,DB2, SYBASE数据库相互转换功能. 将数据库中的表结构和数据保存到EXCEL中. 将EXCEL中的数据,同步到数据库中.