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

2

28

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.

Sepulcher answered 29/3, 2013 at 5:21 Comment(2)
From the thread here: forum.openoffice.org/en/forum/viewtopic.php?f=12&t=38718 I would expect that it would be easier to transform the Word docs to pdf and display that on Android.Sidon
Follow this link i think this is what you need How to render PDF in Android its for pdf i think you can do same for office docs you can send via intent if app is already installed or display in webview with google docs linksStorz
S
7

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.

Sepulcher answered 17/4, 2013 at 6:38 Comment(7)
I can also successfully display the word document using the above library. The only problem is of "Watermark" that's getting displayed in the document. Did you find any other better way to display MS-Word document or have any idea to remove this watermark?Mordent
@YuDroid: No. I haven't found anything better than the OliveDocLibrary solution for this problem. And Yes. Watermark is indeed an issue. Am not working on this project anymore but if you find out any better way. Please share your answer on this thread as I have tried to explore all possible ways and mentioned them right here.Vulcanism
I am trying to open another doc file from sdcard but it gives ActivityNotFoundError (android.content.ActivityNotFoundException: Unable to find explicit activity class {com.olivephone.sdk.view.word.trial/com.olivephone.sdk.word.demo.office.a};) at viu.start(viu.isEncrypted(), "111");Hower
Do you have any solution regarding this @D'yer Mak'er?Hower
Hi @Hower have you posted the question on SO. Give me the link. I'll check and tell you if I can help you with it.Vulcanism
i have created document using IDocument & able to create it successfully, bt when trying to open that with above code, it fails. Bt i will say that the above code works when trying to open another doc file not created from IDocument. So @D'yer can u pls help me out to create doc/docx file programmatically?Hower
Link to the OliveDocLibrary is broken. Could you please share the working linkJaffa
T
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

Temikatemp answered 11/4, 2013 at 5:58 Comment(2)
Hi @RobinHood. Thanks for the reply. It would be really helpful if you could postal a sample code for use of tika to display Word files in android. I searched for a sample code. But cant find any. On the link you have provided they say it uses Apache POI for this operation. this is whats written on the link you posted w.r.t MS files "The OfficeParser and OOXMLParser classes use Apache POI libraries to support text and metadata extraction from both OLE2 and OOXML documents."Vulcanism
hascode.com/2012/12/… #11933262 jworks.nl/2011/09/02/… this are few of links,which doesn't have exact example as you want but you will get reference from it.Temikatemp

© 2022 - 2024 — McMap. All rights reserved.