Apache 公司推出的 Apache POI,我们来看下他的介绍:Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能。
废话少说开始编码,首先我们要下Apache POI的开发jar包,下载地址:http://poi.apache.org/download.html,这里推荐不要下最新版本的,因为一开始我用最新版本的会出一下莫名其妙的问题,后面换旧的版本就OK了。这里我用的是3.9的还是比较稳定的、
开发有2个包,有一点我就非常郁闷Apache居然没有提供api稳定,开发起来还是比较蛋疼的,可能是我自己没有找到把,如果有知道的筒子可以@我、嘿嘿。不过Apache还是提供了Demo大家可以参考。还有我们要准备我们使用的word模板文件、这里我们放在了assets下面了。首先我们来看看怎么使用模板:
1. package com.test.poiword;
2.
3. import android.app.Activity;
4. import android.content.ActivityNotFoundException;
5. import android.content.Intent;
6. import android.net.Uri;
7. import android.os.Bundle;
8. import android.view.View;
9. import android.view.View.OnClickListener;
10. import android.widget.Button;
11. import android.widget.Toast;
12.
13. import com.test.poiword.utils.FileUtils;
14.
15. import org.apache.poi.hwpf.HWPFDocument;
16. import org.apache.poi.hwpf.usermodel.Range;
17.
18. import java.io.ByteArrayOutputStream;
19. import java.io.File;
20. import java.io.FileInputStream;
21. import java.io.FileOutputStream;
22. import java.io.IOException;
23. import java.io.InputStream;
24. import java.util.HashMap;
25. import java.util.Map;
26.
27. public class MainActivity extends Activity {
28. // 模板文集地址
29. private static final String demoPath = "/mnt/sdcard/doc/test.doc";
30. // 创建生成的文件地址
31. private static final String newPath = "/mnt/sdcard/doc/testS.doc";
32. private Button btn,btns;
33. @Override
34. protected void onCreate(Bundle savedInstanceState) {
35. super.onCreate(savedInstanceState);
36. setContentView(R.layout.activity_main);
37. btn=(Button)findViewById(R.id.btn);
38. btns=(Button)findViewById(R.id.btns);
39. btn.setOnClickListener(new OnClickListener() {
40.
41. @Override
42. public void onClick(View arg0) {
43. try {
44. InputStream inputStream = getAssets().open("test.doc");
45. FileUtils.writeFile(new File(demoPath), inputStream);
46. } catch (Exception e) {
47. e.printStackTrace();
48. }
49. doScan();
50. }
51. });
52. btns.setOnClickListener(new OnClickListener() {
53.
54. @Override
55. public void onClick(View arg0) {
56. Intent intent = new Intent(MainActivity.this,WordHtmlActivity.class);
57. startActivity(intent);
58. }
59. });
60.
61. }
62.
63. private void doScan(){
64. //获取模板文件
65. File demoFile=new File(demoPath);
66. //创建生成的文件
67. File newFile=new File(newPath);
68. Map<String, String> map = new HashMap<String, String>();
69. map.put("$QYMC$", "xxx科技股份有限公司");
70. map.put("$QYDZ$", "上海市杨浦区xx路xx号");
71. map.put("$QYFZR$", "张三");
72. map.put("$FRDB$", "李四");
73. map.put("$CJSJ$", "2000-11-10");
74. map.put("$SCPZMSJWT$", "5");
75. map.put("$XCJCJBQ$", "6");
76. map.put("$JLJJJFF$", "7");
77. map.put("$QYFZRQM$", "张三");
78. map.put("$CPRWQM$", "赵六");
79. map.put("$ZFZH$", "100001");
80. map.put("$BZ$", "无");
81. writeDoc(demoFile,newFile,map);
82. //查看
83. doOpenWord();
84. }
85. /**
86. * 调用手机中安装的可打开word的软件
87. */
88. private void doOpenWord(){
89. Intent intent = new Intent();
90. intent.setAction("android.intent.action.VIEW");
91. intent.addCategory("android.intent.category.DEFAULT");
92. String fileMimeType = "application/msword";
93. intent.setDataAndType(Uri.fromFile(new File(newPath)), fileMimeType);
94. try{
95. MainActivity.this.startActivity(intent);
96. } catch(ActivityNotFoundException e) {
97. //检测到系统尚未安装OliveOffice的apk程序
98. Toast.makeText(MainActivity.this, "未找到软件", Toast.LENGTH_LONG).show();
99. //请先到www.olivephone.com/e.apk下载并安装
100. }
101. }
102. /**
103. * demoFile 模板文件
104. * newFile 生成文件
105. * map 要填充的数据
106. * */
107. public void writeDoc(File demoFile ,File newFile ,Map<String, String> map)
108. {
109. try
110. {
111. FileInputStream in = new FileInputStream(demoFile);
112. HWPFDocument hdt = new HWPFDocument(in);
113. // Fields fields = hdt.getFields();
114. // 读取word文本内容
115. Range range = hdt.getRange();
116. // System.out.println(range.text());
117.
118. // 替换文本内容
119. for(Map.Entry<String, String> entry : map.entrySet())
120. {
121. range.replaceText(entry.getKey(), entry.getValue());
122. }
123. ByteArrayOutputStream ostream = new ByteArrayOutputStream();
124. FileOutputStream out = new FileOutputStream(newFile, true);
125. hdt.write(ostream);
126. // 输出字节流
127. out.write(ostream.toByteArray());
128. out.close();
129. ostream.close();
130. }
131. catch(IOException e)
132. {
133. e.printStackTrace();
134. }
135. catch(Exception e)
136. {
137. e.printStackTrace();
138. }
139. }
140.
141. }
上面代码的代码并不多,首先我们要注意的是我们使用的poi的api大部分是在org.apache.poi.hwpf下面的,大家不要导错包了,因为apache每个包对应的内容不同:
上面代码不难懂,就是把我们要放的内容使用特定的代号组装一个map塞到我们的模板里面去,然后重新存储下,不过我们模板也要使用相同的代号、poi才能识别:
这样我们就使用模板大功告成了,就可以查看了、但是有些手机并没有装wps类似的工具,要是手机可以直接查看那就好了,嘿嘿、当然apache肯定也想到了、提供了这样的api下面上代码:
1. package com.test.poiword;
2.
3. import android.os.Bundle;
4. import android.support.v4.app.FragmentActivity;
5. import android.webkit.WebSettings;
6. import android.webkit.WebView;
7.
8. import com.test.poiword.utils.FileUtils;
9.
10. import org.apache.poi.hwpf.HWPFDocument;
11. import org.apache.poi.hwpf.converter.PicturesManager;
12. import org.apache.poi.hwpf.converter.WordToHtmlConverter;
13. import org.apache.poi.hwpf.usermodel.Picture;
14. import org.apache.poi.hwpf.usermodel.PictureType;
15. import org.w3c.dom.Document;
16.
17. import java.io.BufferedWriter;
18. import java.io.ByteArrayOutputStream;
19. import java.io.File;
20. import java.io.FileInputStream;
21. import java.io.FileNotFoundException;
22. import java.io.FileOutputStream;
23. import java.io.IOException;
24. import java.io.OutputStreamWriter;
25. import java.util.List;
26.
27. import javax.xml.parsers.DocumentBuilderFactory;
28. import javax.xml.transform.OutputKeys;
29. import javax.xml.transform.Transformer;
30. import javax.xml.transform.TransformerFactory;
31. import javax.xml.transform.dom.DOMSource;
32. import javax.xml.transform.stream.StreamResult;
33.
34. /**
35. * Created by fuweiwei on 2015/11/28.
36. */
37. public class WordHtmlActivity extends FragmentActivity {
38. //文件存储位置
39. private String docPath = "/mnt/sdcard/doc/";
40. //文件名称
41. private String docName = "test.doc";
42. //html文件存储位置
43. private String savePath = "/mnt/sdcard/doc/";
44. @Override
45. protected void onCreate(Bundle savedInstanceState) {
46. super.onCreate(savedInstanceState);
47. setContentView(R.layout.html);
48. String name = docName.substring(0, docName.indexOf("."));
49. try {
50. convert2Html(docPath + docName, savePath + name + ".html");
51. } catch (Exception e) {
52. e.printStackTrace();
53. }
54. //WebView加载显示本地html文件
55. WebView webView = (WebView)this.findViewById(R.id.office);
56. WebSettings webSettings = webView.getSettings();
57. webSettings.setLoadWithOverviewMode(true);
58. webSettings.setSupportZoom(true);
59. webSettings.setBuiltInZoomControls(true);
60. webView.loadUrl("file:/"+savePath+name+".html");
61. }
62.
63. /**
64. * word文档转成html格式
65. * */
66. public void convert2Html(String fileName, String outPutFile) {
67. HWPFDocument wordDocument = null;
68. try {
69. wordDocument = new HWPFDocument(new FileInputStream(fileName));
70. WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
71. DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
72. //设置图片路径
73. wordToHtmlConverter.setPicturesManager(new PicturesManager() {
74. public String savePicture(byte[] content,
75. PictureType pictureType, String suggestedName,
76. float widthInches, float heightInches) {
77. String name = docName.substring(0, docName.indexOf("."));
78. return name + "/" + suggestedName;
79. }
80. });
81. //保存图片
82. List<Picture> pics=wordDocument.getPicturesTable().getAllPictures();
83. if(pics!=null){
84. for(int i=0;i<pics.size();i++){
85. Picture pic = (Picture)pics.get(i);
86. System.out.println( pic.suggestFullFileName());
87. try {
88. String name = docName.substring(0,docName.indexOf("."));
89. String file = savePath+ name + "/"
90. + pic.suggestFullFileName();
91. FileUtils.makeDirs(file);
92. pic.writeImageContent(new FileOutputStream(file));
93. } catch (FileNotFoundException e) {
94. e.printStackTrace();
95. }
96. }
97. }
98. wordToHtmlConverter.processDocument(wordDocument);
99. Document htmlDocument = wordToHtmlConverter.getDocument();
100. ByteArrayOutputStream out = new ByteArrayOutputStream();
101. DOMSource domSource = new DOMSource(htmlDocument);
102. StreamResult streamResult = new StreamResult(out);
103.
104. TransformerFactory tf = TransformerFactory.newInstance();
105. Transformer serializer = tf.newTransformer();
106. serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
107. serializer.setOutputProperty(OutputKeys.INDENT, "yes");
108. serializer.setOutputProperty(OutputKeys.METHOD, "html");
109. serializer.transform(domSource, streamResult);
110. out.close();
111. //保存html文件
112. writeFile(new String(out.toByteArray()), outPutFile);
113. } catch (Exception e) {
114. e.printStackTrace();
115. }
116. }
117.
118. /**
119. * 将html文件保存到sd卡
120. * */
121. public void writeFile(String content, String path) {
122. FileOutputStream fos = null;
123. BufferedWriter bw = null;
124. try {
125. File file = new File(path);
126. if(!file.exists()){
127. file.createNewFile();
128. }
129. fos = new FileOutputStream(file);
130. bw = new BufferedWriter(new OutputStreamWriter(fos,"utf-8"));
131. bw.write(content);
132. } catch (FileNotFoundException fnfe) {
133. fnfe.printStackTrace();
134. } catch (IOException ioe) {
135. ioe.printStackTrace();
136. } finally {
137. try {
138. if (bw != null)
139. bw.close();
140. if (fos != null)
141. fos.close();
142. } catch (IOException ie) {
143. }
144. }
145. }
146. }
上面的代码的原理起始也很简单,poi提供了让word文档转换成html页面的方法、我们只需要使用webview来加载这个html就ok了,这样我们就可以再手机端直接查看我们的word文档了,是不是好强大。其实看起来的比较复杂的功能只要我们静下心来想想就没有我们想象中的那么复杂,今天就为大家分享到这了。下面有Demo的源码。