Displaying a MS Word File in View(say TextView) in Android

25,372

Solution 1

Hello guys After much consideration and looking at hell lot of options and workarounds I think OliveDocLibrary is the best way to do it. Here is the link which will give direct you to the downloads page of three libraries for Android which are for DOC, XLS and PPT. All these work excellently well. The package folder you will download will have three folders inside. which are:

  1. API
  2. lib_trial
  3. Demo

In the demo folder you will find a sample project for Word. You can directly import this project into your workspace in Eclipse and test the code yourself. For peoples convenience am posting that code here. I have deleted some part of the code which I felt was not necessary(w.r.t the answer to my question here). So the code has two files, The main activity is FileChooser which is as follows:

public class FileChooser extends Activity {

    private String filePath = Environment.getExternalStorageDirectory()
            .getPath() + "/simple.docx";
    MyBaseAdapter adapter;
    private static String parentPath;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(2);
        copyFileToSdcard();
        Intent intent = new Intent(FileChooser.this,
                OliveWordTrailDemoAcitivy.class);
        intent.setAction(Intent.ACTION_VIEW);
        intent.setData(Uri.fromFile(new File(filePath)));
        startActivity(intent);
    }

    class MyBaseAdapter extends BaseAdapter {
        private String[] list;

        public MyBaseAdapter(String[] list) {
            this.list = list;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = new TextView(FileChooser.this);
                ((TextView) convertView).setTextSize(35);
            }
            ((TextView) convertView).setText(list[position]);
            return convertView;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public int getCount() {
            return list.length;
        }

        public void setList(String[] list) {
            this.list = list;
        }
    };

    class MyItemClickListener implements OnItemClickListener {
        String[] list;
        InputStream is;

        public MyItemClickListener(String[] list) {
            this.list = list;
        }

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                long id) {

            File file = new File(parentPath + list[position]);
            if (file.isFile()) {
                Intent intent = new Intent(FileChooser.this,
                        OliveWordTrailDemoAcitivy.class);
                intent.setAction(Intent.ACTION_VIEW);
                intent.setData(Uri.fromFile(file));
                startActivity(intent);
            } else {
                list = file.list();
                adapter.setList(list);
                adapter.notifyDataSetChanged();
                parentPath = file.getAbsolutePath() + "/";
            }
        }

    }
    private void copyFileToSdcard() {
        InputStream inputstream     = getResources().openRawResource(
                R.raw.simple);
        byte[] buffer = new byte[1024];
        int count = 0;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(new File(filePath));
            while ((count = inputstream.read(buffer)) > 0) {
                fos.write(buffer, 0, count);
            }
            fos.close();
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
            Toast.makeText(FileChooser.this, "Check your sdcard", Toast.LENGTH_LONG).show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

Here I have placed a doc file named simple.docx which includes images and mathematical symbols which are rendered and displayed properly. This activity interacts with OliveWordTrialDemoActivity which is as follows:

public class OliveWordTrailDemoAcitivy extends Activity implements
OnClickListener, CommentListener, NoteListener, HyperlinkListener, ProgressListener {

    OliveWordOperator viu;

    EditText searchEditText;
    ArrayList<String> bookmarks;
    Handler handler;

    protected void onCreate(Bundle savedInstanceState) {
        viu = new OliveWordOperator(this, this);
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_PROGRESS);
        setProgressBarVisibility(true);
        getWindow().setFeatureInt(Window.FEATURE_PROGRESS, Window.PROGRESS_VISIBILITY_ON);
        setContentView(R.layout.demo_view);
        OliveWordView view = (OliveWordView) findViewById(R.id.test_view);

        try {
            viu.init(view, getIntent().getData());
            viu.start(viu.isEncrypted(), "111");
        } catch (Exception e) {
            e.printStackTrace();
        }
        handler = new Handler(){

            @Override
            public void handleMessage(Message msg) {
                setProgress(msg.what * 10);
                super.handleMessage(msg);
            }

        };

    }

    @Override
    protected void onDestroy() {
        viu.release();
        super.onDestroy();
    }

    @Override
    public void getComment(ArrayList<String[]> comments) {
        for (int i = 0; i < comments.size(); i++) {
            AlertDialog.Builder builder = new Builder(this);
            builder.setTitle(comments.get(i)[0]).setMessage(comments.get(i)[1])
            .show();
        }
    }

    @Override
    public void getHyperlink(String hyperlink) {
        if (Uri.parse(hyperlink).getScheme().contains("mailto")) {
            try {
                startActivity(new Intent(Intent.ACTION_SENDTO,
                        Uri.parse(hyperlink)));
            } catch (ActivityNotFoundException anfe) {
                Toast.makeText(this, "can't found email application",
                        Toast.LENGTH_SHORT).show();
            }
        } else {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(hyperlink)));
        }
    }

    @Override
    public void getNote(SparseArray<String> notes) {
        for (int i = 0; i < notes.size(); i++) {
            AlertDialog.Builder builder = new Builder(this);
            if (notes.keyAt(i) == NoteListener.FOOTNOTE) {
                builder.setTitle("footnote").setMessage(notes.valueAt(i))
                .show();
            } else if (notes.keyAt(i) == NoteListener.ENDNOTE) {
                builder.setTitle("endnote").setMessage(notes.valueAt(i)).show();
            }
        }

    }

    public void goToBookmarks(String name) {
        viu.goToBookmark(name);
    }

    public void listBookmarks() {
        this.bookmarks = viu.listBookmarks();
    }

    @Override
    public void notifyProgress(int progress) {
        handler.sendEmptyMessage(progress);
    }

    @Override
    public void onClick(View v) {

    }

}

In the lib_trial folder you will find the library which can be added to your libs folder if you want to use it separately.

And in the API folder you will find a detailed description of the library and its methods in form of a pdf file which is very easy to understand. so people can just use this library directly and use the methods provided to their specific requirement.

So that's the solution am going with for now. Any better solutions are welcome. The bounty time is about to get over soon so please provide any other solution you may have as soon as possible. Thanks.

Solution 2

As you mention in your question that you already tried few of library like Jopendocument, OliveDocLibrary and Apache POI but no luck.

Now I want to modify this code so that I can display MS Word files(.docx) which contain text,images and mathematical symbols in between.

While research I came across one more library named Tika, which also used to extract data and its support listed documents and even Libra Office where you can read write and manage documents.

Last suggestion:

You can achieve by converting, doc to html and html to pdf as mention here.

To convert doc to html refer stack-overflow answer

Share:
25,372
D'yer Mak'er
Author by

D'yer Mak'er

Beginner in Android. Worked on SharePoint Portal design before.

Updated on August 05, 2022

Comments

  • D'yer Mak'er
    D'yer Mak'er over 1 year

    I want to display a .docx file in a View in Android. The file has mathematical symbols and also images in between the text. I want to display many such files and flip through them via swipe gesture. I have successfully done the same for .txt files. And can now very easily go to the next page on swipe. The code for .txt file is as follows:

    public String readTxt(String fileName)
        {
    
    
            try {
                InputStream is;
                is = context.getAssets().open(fileName + ".txt");
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    
                int i;
                i = is.read();
                while (i != -1)
                {
                    byteArrayOutputStream.write(i);
                    i = is.read();
                }
    
                is.close();
    
                return byteArrayOutputStream.toString();
    
            } 
    
            catch (IOException e) 
            {
                e.printStackTrace();
            }
    
            return fileName;
        }
    

    This code returns the text which I then display in my TextView. This way I only need to change the name of the file dynamically and on swipe the Text changes.

    Now I want to modify this code so that I can display MS Word files(.docx) which contain text,images and mathematical symbols.

    I have already checked many similar threads on this topic on stack overflow as well as on other forums: These are the links many people have suggested as answers to similar questions and I have already given these a try: Link1 and link2

    Also on many other threads people have recommended Jopendocument. I have also read about that and learnt that Android does not support open document format. so that option seems unlikely. But if you have any workaround or a good detailed explanation with respect to adding the JOpenDocument library to the project and displaying rich text then please share that solution because I have searched for it a lot but couldn't find any.

    There is also another library called OliveDocLibrary to display rich word files on android. here is the link from where I downloaded the lib. The demo included in that download package works just fine.But the lib is a trial version. So am currently trying to work with this library and see where it goes. But am still in search of better options.

    Any help regarding this is appreciated. Any pointers other than the ones mentioned above are most welcome.

    Update:

    I got a suggestion which told the use of Apache POI(HWPF more specifically) in the first bounty I started on this question. After exploring Apache POI for some time, I got few codes which were writing into a doc file, reading the doc file, updating the excel sheets etc.

    Such Sample code(for Java) which I found off the internet goes something like this:

    import java.io.*;
    import org.apache.poi.hwpf.HWPFDocument;
    import org.apache.poi.hwpf.extractor.WordExtractor;
    
    public class ReadDocFile {
    public static void main(String[] args) {
    File file = null;
    WordExtractor extractor = null ;
    try {
    
    file = new File("c:\\New.doc");
    FileInputStream fis=new FileInputStream(file.getAbsolutePath());
    HWPFDocument document=new HWPFDocument(fis);
    extractor = new WordExtractor(document);
    String [] fileData = extractor.getParagraphText();
    for(int i=0;i<fileData.length;i++){
    if(fileData[i] != null)
    System.out.println(fileData[i]);
    }
    }
    catch(Exception exep){}
    }
    }
    

    So I added this library(Apache POI) to my Android project in eclipse and tried this sample code with some changes. And tried displaying it on a TextView. The problem here though is it doesn't display the images like OliveDocLibrary does. So if Someone is going to suggest Apache POI, then I request for a solid pointer or a code which reads a docx file and all its contents(that includes images) and displays them in a custom view.

    Apache POI is a great thing but sadly I didn't find any good examples/samples implementing those libraries. If you know a good source of examples(w.r.t MS word only) then please share them in comments.

    Update 2:

    In OliveDocLibrary package the code provided works fine. There is water mark of Olive on the View though. Currently am working on performing Swipe on that code. But the problem remains that its a trial version.

    Update 3:

    I think OliveDocLibrary is the most efficient way to do it. Though it has a disadvantage of being a trial version, I think no other library does a better job than this library to full fill my specific requirement. The detailed answer has been posted below. As the bounty time is about to get over. I would request the people who may have an alternate and better solution to post it as soon as possible. For now am going with OliveDocLibrary and accepting my own answer.