Android中解析读取复杂word,excel,ppt等的方法

本文介绍如何在Android中解析读取复杂的Word、Excel和PPT文档,传统方法如tm-extractors-0.4.jar和jxl.jar效果不佳。作者通过HTML解析,利用POI库展示了保留格式和内容的读取方法,包括图片、表格和附件。代码示例已上传至CSDN。
摘要由CSDN通过智能技术生成

        前段时间在尝试做一个Android里的万能播放器,能播放各种格式的软件,其中就涉及到了最常用的office软件。查阅了下资料,发现Android中最传统的直接解析读取word,excel的方法主要用了java里第三方包,比如利用tm-extractors-0.4.jar和jxl.jar等,下面附上代码和效果图。

        读取word用了tm-extractors-0.4.jar包,代码如下:

  

package com.example.readword;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import org.textmining.text.extraction.WordExtractor;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.widget.TextView;


public class MainActivity extends Activity {
    /** Called when the activity is first created. */

    private TextView text;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        text = (TextView) findViewById(R.id.text);

        String str = readWord("/storage/emulated/0/ArcGIS/localtilelayer/11.doc");
        text.setText(str.trim().replace("", ""));
    }

    public String readWord(String file){
        //创建输入流用来读取doc文件
        FileInputStream in;
        String text = null;
        try {
            in = new FileInputStream(new File(file));
            WordExtractor extractor = null;
            //创建WordExtractor
            extractor = new WordExtractor();
            //进行提取对doc文件
            text = extractor.extractText(in);
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return text;
    }
}

        效果图如下:



       只是从网上随便下载的一个文档,我们可以看出,虽然能读取,但是格式的效果并不佳,而且只能读取doc,不能读取docx格式,也不能读取doc里的图片。另外就是加入使用WPF打开过这个doc的话,将无法再次读取(对于只安装WPF的我简直是个灾难)

       然后是用jxl读取excel的代码,这个代码不是很齐,就写了个解析的,将excel里每行每列都解析了出来,然后自己可以重新再编辑,代码如下:

     

package com.readexl;

import java.io.FileInputStream;
import java.io.InputStream;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.text.method.ScrollingMovementMethod;
import android.view.Menu;
import android.widget.TextView;

import jxl.*;

public class MainActivity extends Activity {
    TextView txt = null;
    public String filePath_xls = Environment.getExternalStorageDirectory()
            + "/case.xls";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        txt = (TextView)findViewById(R.id.txt_show);
        txt.setMovementMethod(ScrollingMovementMethod.getInstance());
        readExcel();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    public void readExcel() {
        try {
            /**
             * 后续考虑问题,比如Excel里面的图片以及其他数据类型的读取
             **/

            InputStream is = new FileInputStream(filePath_xls);
            //Workbook book = Workbook.getWorkbook(new File("mnt/sdcard/test.xls"));
            Workbook book = Workbook.getWorkbook(is);

            int num = book.getNumberOfSheets();
            txt.setText("the num of sheets is " + num+ "\n");
            // 获得第一个工作表对象
            Sheet sheet = book.getSheet(0);
            int Rows = sheet.getRows();
            int Cols = sheet.getColumns();
            txt.append("the name of sheet is " + sheet.getName() + "\n");
            txt.append("total rows is " + Rows + "\n");
            txt.append("total cols is " + Cols + "\n");
            for (int i = 0; i < Cols; ++i) {
                for (int j = 0; j < Rows; ++j) {
                    // getCell(Col,Row)获得单元格的值
                    txt.append("contents:" + sheet.getCell(i,j).getContents() + "\n");
                }
            }
            book.close();
        } catch (Exception e) {
            System.out.println(e);
        }
    }

}

效果图如下:

        

       好吧,这只是个半成品,不过,这个方法肯定是行得通的。

       之前说了这么多,很明白的意思就是我对于这两种方法都不是很满意。在这里,我先说下doc和docx的区别(xls和xlsx,ppt和pptx等区别都和此类似)

       众所周知的是doc03及之前版本word所保存的格式,docx07版本之后保存的格式,简单的说,在doc中,微软还是用二进制存储方式;在docx中微软开始用xml方式,docx实际上成了一个打包的ZIP压缩文件。doc解压得到的是没有扩展名的文件碎片,而docx解压可以得到一个XML和几个包含信息的文件夹。两者比较的结论就是docx更小,而且要读取图片更容易。(参考http://www.zhihu.com/question/21547795)

  好吧,回到正题。如何才能解析各种word,excel等能保留原来格式并且解析里面的图片,表格或附件等内容呢。那当然就是html了!不得不承认html对于页面,表格等展示的效果确是是很强大的,原生很难写出这样的效果。在网上找了诸多的资料,以及各个大神的代码,自己又再此基础上修改了下,实现的效果还不错吧。

  利用的包是POI(一堆很强大的包,可以解析几乎所有的office软件,这里以doc,docx,xls,xlsx为例)


读取文件后根据不同文件类型分别进行操作。

public void read() {
 
    if(!myFile.exists()){
        if (this.nameStr.endsWith(".doc")) {
            this.getRange();
            this.makeFile();
            this.readDOC();
        }
        if (this.nameStr.endsWith(".docx")) {
            this.makeFile();
            this.readDOCX();
        }
        if (this.nameStr.endsWith(".xls")) {
            try {
                this.makeFile();
                this.readXLS();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if (this.nameStr.endsWith(".xlsx")) {
            try{
                this.makeFile();
                this.readXLSX();
            }catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    returnPath = "file:///" + myFile;
    // this.view.loadUrl("file:///" + this.htmlPath);
    System.out.println("htmlPath" + this.htmlPath);

}
先贴上公用的方法,主要是设置生成的html文件保存地址:

public void makeFile() {
    String sdStateString = android.os.Environment.getExternalStorageState();// 获取外部存储状态
    if (sdStateString.equals(android.os.Environment.MEDIA_MOUNTED)) {
 // 确认sd卡存在,原理不知,媒体安装??
        try {
            File sdFile = android.os.Environment
                    .getExternalStorageDirectory();// 获取扩展设备的文件目录
            String path = sdFile.getAbsolutePath() + File.separator
                    + "library";// 得到sd卡(扩展设备)的绝对路径+"/"+xiao
            File dirFile = new File(path);// 获取xiao文件夹地址
            if (!dirFile.exists()) {
 // 如果不存在
                dirFile.mkdir();// 创建目录
            }
            File myFile = new File(path + File.separator +filename+ ".html");// 获取my.html的地址
            if (!myFile.exists()) {
 // 如果不存在
                myFile.createNewFile();// 创建文件
            }
            this.htmlPath = myFile.getAbsolutePath();// 返回路径
        } catch (Exception e) {
        }
    }
}
然后是读取doc:

private void getRange() {
    FileInputStream in = null;
    POIFSFileSystem pfs = null;

    try {
        in = new FileInputStream(nameStr);
        pfs = new POIFSFileSystem(in);
        hwpf = new HWPFDocument(pfs);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    range = hwpf.getRange();

    pictures = hwpf.getPicturesTable().getAllPictures();

    tableIterator = new TableIterator(range);

}
public void readDOC() {

    try {
        myFile = new File(htmlPath);
        output = new FileOutputStream(myFile);
        presentPicture=0;
        String head = "<
评论 295
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值