之前通过第三方jar包tm-extractors-0.4.jar,实现了一个简单的读取word文件的demo,但是只能读取word的文本数据,无法读取图片、表格数据。
最近参考网上的例子http://blog.csdn.net/xiaoxiaobian3310903/article/details/6598500 终于能够读取word里面的图片,表格等内容。在android系统上读取Word格式文档基于的开源包--POI(The Java API For Microsoft Documents)。两个jar包 poi-3.7-20101029.jar和 poi-scratchpad-3.7-20101029.jar
大致实现的过程是这样的:
在目录中选择要打开的word文件(.doc);
将Word格式文档中的内容读取出来,判断当前读取的段落是文本、图片、还是表格,然后加上对应的HTML标签,生成一个html文件;
然后通过一个WebView对生成的html文件进行显示。
首先是SD卡根目录选择文件
import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.SimpleAdapter; public class Browse extends Activity { private ListView listV = null; private List<File> list = null; private int a[] = {R.drawable.doc,R.drawable.dir}; private ArrayList<HashMap<String, Object>> recordItem; private File presentFile; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.browse); listV = (ListView)findViewById(R.id.list); list_files(); } private void list_files(){ //得到SD卡根目录 File path = android.os.Environment.getExternalStorageDirectory(); presentFile = path; File[] file = path.listFiles(); fill(file); } private void fill(File[] file){ SimpleAdapter adapter = null; recordItem = new ArrayList<HashMap<String, Object>>(); list = new ArrayList<File>(); for(File f: file){ if(Invalid(f) == 1){ list.add(f); HashMap<String, Object> map = new HashMap<String, Object>(); map.put("picture", a[0]); map.put("name", f.getName()); recordItem.add(map); } if(Invalid(f) == 0){ list.add(f); HashMap<String, Object> map = new HashMap<String, Object>(); map.put("picture", a[1]); map.put("name", f.getName()); recordItem.add(map); } } adapter = new SimpleAdapter(this, recordItem, R.layout.item, new String[]{"picture", "name"}, new int[]{R.id.picture, R.id.text}); listV.setAdapter(adapter); listV.setAdapter(adapter); listV.setOnItemClickListener(new Clicker()); } private int Invalid(File f){ if(f.isDirectory()){ return 0; } else{ String filename = f.getName().toLowerCase(); if(filename.endsWith(".doc")){ return 1; } return 2; } } private class Clicker implements AdapterView.OnItemClickListener { public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub Intent i = new Intent(); String nameStr = null; i.setClass(Browse.this, ViewFile.class); Bundle bundle = new Bundle(); File file = list.get(arg2); presentFile = file; if(file.isDirectory()){ File[] files = file.listFiles(); fill(files); } else{ nameStr = file.getAbsolutePath(); bundle.putString("name", nameStr); i.putExtras(bundle); startActivity(i); finish(); } } } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if(presentFile.isDirectory()){ if(presentFile.equals(android.os.Environment.getExternalStorageDirectory())){ this.finish(); } else{ presentFile = presentFile.getParentFile(); File file = presentFile; File[] files = file.listFiles(); fill(files); } } if(presentFile.isFile()){ if(presentFile.getParentFile().isDirectory()){ presentFile = presentFile.getParentFile(); File file = presentFile; File[] files = file.listFiles(); fill(files); } } } return false; } }
然后,选择word文档,在WebView上显示读取的html文件
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.List; import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.usermodel.CharacterRun; import org.apache.poi.hwpf.usermodel.Paragraph; import org.apache.poi.hwpf.usermodel.Picture; import org.apache.poi.hwpf.usermodel.Range; import org.apache.poi.hwpf.usermodel.Table; import org.apache.poi.hwpf.usermodel.TableCell; import org.apache.poi.hwpf.usermodel.TableIterator; import org.apache.poi.hwpf.usermodel.TableRow; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.webkit.WebView; import android.webkit.WebViewClient; /** * Created by Administrator on 2016/4/11. */ public class ViewFile extends Activity { private String nameStr = null; private Range range = null; private HWPFDocument hwpf = null; private String htmlPath; private String picturePath; private WebView view; private List pictures; private TableIterator tableIterator; private int presentPicture = 0; private int screenWidth; private FileOutputStream output; private File myFile; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.view); view = (WebView)findViewById(R.id.show); screenWidth = this.getWindowManager().getDefaultDisplay().getWidth() - 10; Intent intent = this.getIntent(); Bundle bundle = intent.getExtras(); nameStr = bundle.getString("name"); getRange(); makeFile(); readAndWrite(); // view.loadUrl("content://com.android.htmlfileprovider/" + htmlPath); // view.loadUrl("http://m.oschina.net"); // view.loadUrl("file:///mnt/sdcard/haha.html"); view.loadUrl("file:///"+htmlPath); view.getSettings().setJavaScriptEnabled(true); view.setWebViewClient(new WebViewClient()); System.out.println("htmlPath" + htmlPath); } public boolean onCreateOptionsMenu(Menu menu){ super.onCreateOptionsMenu(menu); menu.add(0, 0, 0, "关于文件").setIcon(this.getResources().getDrawable(R.drawable.importdb)); menu.add(0, 1, 1, "关于作者").setIcon(this.getResources().getDrawable(R.drawable.exportdb)); return true; } public boolean onOptionsItemSelected(MenuItem item){ switch(item.getItemId()){ case 0: showDialog(0); break; case 1: showDialog(1); break; } return super.onOptionsItemSelected(item); } protected Dialog onCreateDialog(int id){ switch(id){ case 0: return buildDialogProgram(ViewFile.this); case 1: return buildDialogAuthor(ViewFile.this); } return null; } private Dialog buildDialogAuthor(Context context){ AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setIcon(this.getResources().getDrawable(R.drawable.dslab)); builder.setTitle(this.getResources().getString(R.string.aboutauthor)); builder.setMessage(this.getResources().getString(R.string.author)); builder.setPositiveButton(this.getResources().getString(R.string.gotit), new DialogInterface.OnClickListener(){ public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub dialog.dismiss(); } }); return builder.create(); } private Dialog buildDialogProgram(Context context){ AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(this.getResources().getString(R.string.aboutprogram)); builder.setIcon(this.getResources().getDrawable(R.drawable.importdb)); String programInfo = this.getResources().getString(R.string.word) + hwpf.characterLength() + " "; programInfo = programInfo + this.getResources().getString(R.string.paragrap) + range.numParagraphs() + " "; programInfo = programInfo + this.getResources().getString(R.string.pictures) + pictures.size() + " "; builder.setMessage(programInfo); builder.setPositiveButton(this.getResources().getString(R.string.gotit), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub dialog.dismiss(); } }); return builder.create(); } public void makeFile(){ String sdStateString = android.os.Environment.getExternalStorageState(); if(sdStateString.equals(android.os.Environment.MEDIA_MOUNTED)){ try{ File sdFile = android.os.Environment.getExternalStorageDirectory(); // String path = sdFile.getAbsolutePath() + File.separator + "xiao"; String path = sdFile.getAbsolutePath() ; String temp = path + File.separator + "my.html"; File dirFile = new File(path); if(!dirFile.exists()){ dirFile.mkdir(); } File myFile = new File(path + File.separator + "my.html"); if(!myFile.exists()){ myFile.createNewFile(); } htmlPath = myFile.getAbsolutePath(); } catch(Exception e){ } } } /*用来在sdcard上创建图片*/ public void makePictureFile(){ String sdString = android.os.Environment.getExternalStorageState(); if(sdString.equals(android.os.Environment.MEDIA_MOUNTED)){ try{ File picFile = android.os.Environment.getExternalStorageDirectory(); String picPath = picFile.getAbsolutePath() + File.separator + "xiao"; File picDirFile = new File(picPath); if(!picDirFile.exists()){ picDirFile.mkdir(); } File pictureFile = new File(picPath + File.separator + presentPicture + ".jpg"); if(!pictureFile.exists()){ pictureFile.createNewFile(); } picturePath = pictureFile.getAbsolutePath(); } catch(Exception e){ System.out.println("PictureFile Catch Exception"); } } } public void onDestroy(){ super.onDestroy(); } /*读取word中的内容写到sdcard上的.html文件中*/ public void readAndWrite(){ try{ myFile = new File(htmlPath); output = new FileOutputStream(myFile); String head = "<html><body>"; String tagBegin = "<p>"; String tagEnd = "</p>"; output.write(head.getBytes()); int numParagraphs = range.numParagraphs(); for(int i = 0; i < numParagraphs; i++){ Paragraph p = range.getParagraph(i); if(p.isInTable()){ int temp = i; if(tableIterator.hasNext()){ String tableBegin = "<table style="border-collapse:collapse" border=1 bordercolor="black">"; String tableEnd = "</table>"; String rowBegin = "<tr>"; String rowEnd = "</tr>"; String colBegin = "<td>"; String colEnd = "</td>"; Table table = tableIterator.next(); output.write(tableBegin.getBytes()); int rows = table.numRows(); for( int r = 0; r < rows; r++){ output.write(rowBegin.getBytes()); TableRow row = table.getRow(r); int cols = row.numCells(); int rowNumParagraphs = row.numParagraphs(); int colsNumParagraphs = 0; for( int c = 0; c < cols; c++){ output.write(colBegin.getBytes()); TableCell cell = row.getCell(c); int max = temp + cell.numParagraphs(); colsNumParagraphs = colsNumParagraphs + cell.numParagraphs(); for(int cp = temp; cp < max; cp++){ Paragraph p1 = range.getParagraph(cp); output.write(tagBegin.getBytes()); writeParagraphContent(p1); output.write(tagEnd.getBytes()); temp++; } output.write(colEnd.getBytes()); } int max1 = temp + rowNumParagraphs; for(int m = temp + colsNumParagraphs; m < max1; m++){ Paragraph p2 = range.getParagraph(m); temp++; } output.write(rowEnd.getBytes()); } output.write(tableEnd.getBytes()); } i = temp; } else{ output.write(tagBegin.getBytes()); writeParagraphContent(p); output.write(tagEnd.getBytes()); } } String end = "</body></html>"; output.write(end.getBytes()); output.close(); } catch(Exception e){ System.out.println("readAndWrite Exception"); } } /*以段落的形式来往html文件中写内容*/ public void writeParagraphContent(Paragraph paragraph){ Paragraph p = paragraph; int pnumCharacterRuns = p.numCharacterRuns(); for( int j = 0; j < pnumCharacterRuns; j++){ CharacterRun run = p.getCharacterRun(j); if(run.getPicOffset() == 0 || run.getPicOffset() >= 1000){ if(presentPicture < pictures.size()){ writePicture(); } } else{ try{ String text = run.text(); if(text.length() >= 2 && pnumCharacterRuns < 2){ output.write(text.getBytes()); } else{ int size = run.getFontSize(); int color = run.getColor(); String fontSizeBegin = "<font size="" + decideSize(size) + "">"; String fontColorBegin = "<font color="" + decideColor(color) + "">"; String fontEnd = "</font>"; String boldBegin = "<b>"; String boldEnd = "</b>"; String islaBegin = "<i>"; String islaEnd = "</i>"; output.write(fontSizeBegin.getBytes()); output.write(fontColorBegin.getBytes()); if(run.isBold()){ output.write(boldBegin.getBytes()); } if(run.isItalic()){ output.write(islaBegin.getBytes()); } output.write(text.getBytes()); if(run.isBold()){ output.write(boldEnd.getBytes()); } if(run.isItalic()){ output.write(islaEnd.getBytes()); } output.write(fontEnd.getBytes()); output.write(fontEnd.getBytes()); } } catch(Exception e){ System.out.println("Write File Exception"); } } } } /*将word中的图片写入到.jpg文件中*/ public void writePicture(){ Picture picture = (Picture)pictures.get(presentPicture); byte[] pictureBytes = picture.getContent(); Bitmap bitmap = BitmapFactory.decodeByteArray(pictureBytes, 0, pictureBytes.length); makePictureFile(); presentPicture++; File myPicture = new File(picturePath); try{ FileOutputStream outputPicture = new FileOutputStream(myPicture); outputPicture.write(pictureBytes); outputPicture.close(); } catch(Exception e){ System.out.println("outputPicture Exception"); } String imageString = "<img src="" + picturePath + """; if(bitmap.getWidth() > screenWidth){ imageString = imageString + " " + "width="" + screenWidth + """; } imageString = imageString + ">"; try{ output.write(imageString.getBytes()); } catch(Exception e){ System.out.println("output Exception"); } } /*处理word和html字体的转换*/ public int decideSize(int size){ if(size >= 1 && size <= 8){ return 1; } if(size >= 9 && size <= 11){ return 2; } if(size >= 12 && size <= 14){ return 3; } if(size >= 15 && size <= 19){ return 4; } if(size >= 20 && size <= 29){ return 5; } if(size >= 30 && size <= 39){ return 6; } if(size >= 40){ return 7; } return 3; } /*处理word和html颜色的转换*/ private String decideColor(int a){ int color = a; switch(color){ case 1: return "#000000"; case 2: return "#0000FF"; case 3: case 4: return "#00FF00"; case 5: case 6: return "#FF0000"; case 7: return "#FFFF00"; case 8: return "#FFFFFF"; case 9: return "#CCCCCC"; case 10: case 11: return "#00FF00"; case 12: return "#080808"; case 13: case 14: return "#FFFF00"; case 15: return "#CCCCCC"; case 16: return "#080808"; default: return "#000000"; } } private void getRange(){ FileInputStream in = null; POIFSFileSystem pfs = null; try{ in = new FileInputStream(nameStr); pfs = new POIFSFileSystem(in); hwpf = new HWPFDocument(pfs); } catch(Exception e){ } range = hwpf.getRange(); pictures = hwpf.getPicturesTable().getAllPictures(); tableIterator = new TableIterator(range); } /*处理点击返回按钮*/ public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { Intent intent = new Intent(); intent.setClass(ViewFile.this, Browse.class); startActivity(intent); this.finish(); } return false; } }
最后别忘了添加权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"> </uses-permission>
运行的结果
运行完后,发现两个问题
1.图片不能按正常尺寸显示
2.没有word文档缩放的功能
在ViewFile类的writePicture()方法中,虽然对图片的宽度进行了判断,如果大于屏幕的宽度,就让图片的宽度等于屏幕的宽度,但是调试结果发现,图片宽度小于屏幕宽度,但显示的时候却大于屏幕宽度
String imageString = "<img src="" + picturePath + """;
if(bitmap.getWidth() > screenWidth){ imageString = imageString + " " + "width="" + screenWidth + """; } imageString = imageString + ">";
-----------------------------------------------------