Android使用模板生成支持手機直接查看的Word文檔

這篇文章主要爲大家詳細介紹了Android 使用模板生成Word文檔,支持手機直接查看word,具有一定的參考價值,感興趣的小夥伴們可以參考一下

最近在項目工作中,碰到一個很棘手的需求,說是要在手機端根據模板生成word文檔,而且不借助第三方的軟件可以查看word文檔,一開始聽這個需求差不多蒙了,這要怎麼做,爲什麼不把生成word文檔這個工作放在後臺呢,抱怨歸抱怨,但是面對需求只能硬着頭皮做了,經過各種拷問度娘和谷哥,終於找了一個比較好用的方法。特此跟他家分享。

Apache 公司推出的 Apache POI,我們來看下他的介紹:Apache POI 是用Java編寫的免費開源的跨平臺的 Java API,Apache POI提供API給Java程式對Microsoft Office格式檔案讀和寫的功能。

廢話少說開始編碼,首先我們要下Apache POI的開發jar包,下載地址,這裏推薦不要下最新版本的,因爲一開始我用最新版本的會出一下莫名其妙的問題,後面換舊的版本就OK了。這裏我用的是3.9的還是比較穩定的、

開發有2個包,有一點我就非常鬱悶Apache居然沒有提供api穩定,開發起來還是比較蛋疼的,可能是我自己沒有找到把,如果有知道的筒子可以@我、嘿嘿。不過Apache還是提供了Demo大家可以參考。還有我們要準備我們使用的word模板文件、這裏我們放在了assets下面了。首先我們來看看怎麼使用模板:

package com.test.poiword;
 
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
 
import com.test.poiword.utils.FileUtils;
 
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;
 
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
 
public class MainActivity extends Activity {
 // 模板文集地址
 private static final String demoPath = "/mnt/sdcard/doc/test.doc";
 // 創建生成的文件地址
 private static final String newPath = "/mnt/sdcard/doc/testS.doc";
 private Button btn,btns;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 btn=(Button)findViewById(R.id.btn);
 btns=(Button)findViewById(R.id.btns);
 btn.setOnClickListener(new OnClickListener() {
 
 @Override
 public void onClick(View arg0) {
 try {
  InputStream inputStream = getAssets().open("test.doc");
  FileUtils.writeFile(new File(demoPath), inputStream);
 } catch (Exception e) {
  e.printStackTrace();
 }
 doScan();
 }
 });
 btns.setOnClickListener(new OnClickListener() {
 
 @Override
 public void onClick(View arg0) {
 Intent intent = new Intent(MainActivity.this,WordHtmlActivity.class);
 startActivity(intent);
 }
 });
 
 }
 
 private void doScan(){
 //獲取模板文件
 File demoFile=new File(demoPath);
 //創建生成的文件
 File newFile=new File(newPath);
 Map<String, String> map = new HashMap<String, String>();
 map.put("$QYMC$", "xxx科技股份有限公司");
 map.put("$QYDZ$", "上海市楊浦區xx路xx號");
 map.put("$QYFZR$", "張三");
 map.put("$FRDB$", "李四");
 map.put("$CJSJ$", "2000-11-10");
 map.put("$SCPZMSJWT$", "5");
 map.put("$XCJCJBQ$", "6");
 map.put("$JLJJJFF$", "7");
 map.put("$QYFZRQM$", "張三");
 map.put("$CPRWQM$", "趙六");
 map.put("$ZFZH$", "100001");
 map.put("$BZ$", "無");
 writeDoc(demoFile,newFile,map);
 //查看
 doOpenWord();
 }
 /**
 * 調用手機中安裝的可打開word的軟件
 */
 private void doOpenWord(){
 Intent intent = new Intent();
 intent.setAction("android.intent.action.VIEW");
 intent.addCategory("android.intent.category.DEFAULT");
 String fileMimeType = "application/msword";
 intent.setDataAndType(Uri.fromFile(new File(newPath)), fileMimeType);
 try{
 MainActivity.this.startActivity(intent);
 } catch(ActivityNotFoundException e) {
 //檢測到系統尚未安裝OliveOffice的apk程序
 Toast.makeText(MainActivity.this, "未找到軟件", Toast.LENGTH_LONG).show();
 //請先到www.olivephone.com/e.apk下載並安裝
 }
 }
 /**
 * demoFile 模板文件
 * newFile 生成文件
 * map 要填充的數據
 * */
 public void writeDoc(File demoFile ,File newFile ,Map<String, String> map)
 {
 try
 {
 FileInputStream in = new FileInputStream(demoFile);
 HWPFDocument hdt = new HWPFDocument(in);
 // Fields fields = hdt.getFields();
 // 讀取word文本內容
 Range range = hdt.getRange();
 // System.out.println(range.text());
 
 // 替換文本內容
 for(Map.Entry<String, String> entry : map.entrySet())
 {
 range.replaceText(entry.getKey(), entry.getValue());
 }
 ByteArrayOutputStream ostream = new ByteArrayOutputStream();
 FileOutputStream out = new FileOutputStream(newFile, true);
 hdt.write(ostream);
 // 輸出字節流
 out.write(ostream.toByteArray());
 out.close();
 ostream.close();
 }
 catch(IOException e)
 {
 e.printStackTrace();
 }
 catch(Exception e)
 {
 e.printStackTrace();
 }
 }
 
}

上面代碼的代碼並不多,首先我們要注意的是我們使用的poi的api大部分是在org.apache.poi.hwpf下面的,大家不要導錯包了,因爲apache每個包對應的內容不同:

上面代碼不難懂,就是把我們要放的內容使用特定的代號組裝一個map塞到我們的模板裏面去,然後重新存儲下,不過我們模板也要使用相同的代號、poi才能識別:

這樣我們就使用模板大功告成了,就可以查看了、但是有些手機並沒有裝wps類似的工具,要是手機可以直接查看那就好了,嘿嘿、當然apache肯定也想到了、提供了這樣的api下面上代碼:

package com.test.poiword;
 
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.webkit.WebSettings;
import android.webkit.WebView;
 
import com.test.poiword.utils.FileUtils;
 
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.PicturesManager;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.usermodel.PictureType;
import org.w3c.dom.Document;
 
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.List;
 
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
 
/**
 * Created by fuweiwei on 2015/11/28.
 */
public class WordHtmlActivity extends FragmentActivity {
 //文件存儲位置
 private String docPath = "/mnt/sdcard/doc/";
 //文件名稱
 private String docName = "test.doc";
 //html文件存儲位置
 private String savePath = "/mnt/sdcard/doc/";
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.html);
 String name = docName.substring(0, docName.indexOf("."));
 try {
 convert2Html(docPath + docName, savePath + name + ".html");
 } catch (Exception e) {
 e.printStackTrace();
 }
 //WebView加載顯示本地html文件
 WebView webView = (WebView)this.findViewById(R.id.office);
 WebSettings webSettings = webView.getSettings();
 webSettings.setLoadWithOverviewMode(true);
 webSettings.setSupportZoom(true);
 webSettings.setBuiltInZoomControls(true);
 webView.loadUrl("file:/"+savePath+name+".html");
 }
 
 /**
 * word文檔轉成html格式
 * */
 public void convert2Html(String fileName, String outPutFile) {
 HWPFDocument wordDocument = null;
 try {
 wordDocument = new HWPFDocument(new FileInputStream(fileName));
 WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
  DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
 //設置圖片路徑
 wordToHtmlConverter.setPicturesManager(new PicturesManager() {
 public String savePicture(byte[] content,
   PictureType pictureType, String suggestedName,
   float widthInches, float heightInches) {
  String name = docName.substring(0, docName.indexOf("."));
  return name + "/" + suggestedName;
 }
 });
 //保存圖片
 List<Picture> pics=wordDocument.getPicturesTable().getAllPictures();
 if(pics!=null){
 for(int i=0;i<pics.size();i++){
  Picture pic = (Picture)pics.get(i);
  System.out.println( pic.suggestFullFileName());
  try {
  String name = docName.substring(0,docName.indexOf("."));
  String file = savePath+ name + "/"
  + pic.suggestFullFileName();
  FileUtils.makeDirs(file);
  pic.writeImageContent(new FileOutputStream(file));
  } catch (FileNotFoundException e) {
  e.printStackTrace();
  }
 }
 }
 wordToHtmlConverter.processDocument(wordDocument);
 Document htmlDocument = wordToHtmlConverter.getDocument();
 ByteArrayOutputStream out = new ByteArrayOutputStream();
 DOMSource domSource = new DOMSource(htmlDocument);
 StreamResult streamResult = new StreamResult(out);
 TransformerFactory tf = TransformerFactory.newInstance();
 Transformer serializer = tf.newTransformer();
 serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
 serializer.setOutputProperty(OutputKeys.INDENT, "yes");
 serializer.setOutputProperty(OutputKeys.METHOD, "html");
 serializer.transform(domSource, streamResult);
 out.close();
 //保存html文件
 writeFile(new String(out.toByteArray()), outPutFile);
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
 /**
 * 將html文件保存到sd卡
 * */
 public void writeFile(String content, String path) {
 FileOutputStream fos = null;
 BufferedWriter bw = null;
 try {
 File file = new File(path);
 if(!file.exists()){
 file.createNewFile();
 }
 fos = new FileOutputStream(file);
 bw = new BufferedWriter(new OutputStreamWriter(fos,"utf-8"));
 bw.write(content);
 } catch (FileNotFoundException fnfe) {
 fnfe.printStackTrace();
 } catch (IOException ioe) {
 ioe.printStackTrace();
 } finally {
 try {
 if (bw != null)
  bw.close();
 if (fos != null)
  fos.close();
 } catch (IOException ie) {
 }
 }
 }
}

上面的代碼的原理起始也很簡單,poi提供了讓word文檔轉換成html頁面的方法、我們只需要使用webview來加載這個html就ok了,這樣我們就可以再手機端直接查看我們的word文檔了,是不是好強大。其實看起來的比較複雜的功能只要我們靜下心來想想就沒有我們想象中的那麼複雜,今天就爲大家分享到這了。

分享Demo的源碼:Android使用模板生成Word文檔

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持神馬文庫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章