Android使用模板生成支持手机直接查看的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文档

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android自定义PasswordInputView密码输入

    欢迎来到"实现自定义密码输入控件"这一章节,PasswordInputView定义了密码输入的监听,支持直接在布局文件定义属性值.支持直接获取密码输入的长度.原始密码-- 先上图 PasswordInputView是做什么的? PasswordInputView是一个自定义密码输入的控件,类似支付宝.微信支付的密码输入,同时定义了密码输入的监听,支持直接在布局文件定义属性值.支持直接获取密码输入的长度.原始密码等,还可以扩展其他方法,请自行实现. 实现原理 1.创建一个类 'Passw

  • Android 下载并打开PDF,Doc,Dwg文档实例

    今天项目中遇到这样一个需求 ,根据后台接口里pdf,doc,dwg文档的地址 是一个URL ,需要根据文档的url 下载到本地(内部存储或内存卡)并用手机中能打开该文档的软件弹出来并打开,(这里需要做一个缓存,第一次查看这个文档是在服务器上下载并打开,以后打开不需要下载直接打开本地的文档)在网上找了些资料 写了以下代码,下面分享给大家; 效果图: 代码: 这是一个单独的类 首先接收intent传过来的url我是用url的后14位作为存储本地的文件名(这里根据自己服务器的文件命名规则而定) 拿到文

  • android手机端与PC端使用adb forword通信

    PC端与Android手机端使用adb forword通信 服务器端代码如下: import java.io.IOException; import java.io.ObjectOutputStream; import java.net.Socket; import java.net.UnknownHostException; import java.util.Scanner; public class Server { public static final String TAG = "ser

  • Android实现pdf在线预览或本地预览的方法

    最近项目中需要使用在线预览pdf,并要能实现自动播放,我想这样的需求无论如何来说都是很操蛋的 由于本人水平有限,最后讨论将项目需求改成将pdf下载到本地再实现自动播放. 接下来总结下目前能够实现pdf阅读的方案,开发当中需要根据实际需求去选择相应的方案. 1.使用Google doc支持来展示word,excel,pdf,txt(WebView方式在线预览): <span style="font-size:18px;">WebView urlWebView = (WebVi

  • Android webview转PDF的方法示例

    1.网上找了好多没有显示出来效果不错,后来看到调用手机打印预览,看了效果还不错,就打算使用系统打印服务预览下载 2.'webView.createPrintDocumentAdapter()'得到打印的PrintDocumentAdapter有了该类就可以使用onWrite方法写入制定的文件,但是这个方法需要传入回调这个悲剧的是这个回调方法是hiden的我们没办法调用 3,字怎么解决呢,有连个方法 3.1 使用此开源库替换自己的sdk 中的android.jar文件,就可以使用了 https:/

  • Android NDK开发简单程序分享(Hello Word!)

    在之前的博客中已经为大家介绍了,如何在win环境下配置DNK程序,本篇我将带大家实现一个简单的Hello jni程序,让大家真正感受一下NDK开发的魅力.这里我们选择使用C+JAVA开发Android程序,首先你必须了解C语言.JAVA语言以及Linux操作系统,这样可以帮助你开始上手,当然不是说你必须是大牛才能进行NDK开发,下面我们来一起实现一个简单的NDK程序. 第一步,创建Android工程 打开开发环境eclipse,在左侧空白区域,右键单击创建Android工程(非常简单,不再赘述)

  • Android使用模板生成支持手机直接查看的Word文档

    最近在项目工作中,碰到一个很棘手的需求,说是要在手机端根据模板生成word文档,而且不借助第三方的软件可以查看word文档,一开始听这个需求差不多蒙了,这要怎么做,为什么不把生成word文档这个工作放在后台呢,抱怨归抱怨,但是面对需求只能硬着头皮做了,经过各种拷问度娘和谷哥,终于找了一个比较好用的方法.特此跟他家分享. Apache 公司推出的 Apache POI,我们来看下他的介绍:Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给

  • asp.net下用Aspose.Words for .NET动态生成word文档中的数据表格的方法

    1.概述 最近项目中有一个这样的需求:导出word 文档,要求这个文档的格式不是固定的,用户可以随便的调整,导出内容中的数据表格列是动态的,例如要求导出姓名和性别,你就要导出这两列的数据,而且这个文档不是导出来之后再调整而是导出来后已经是调整过了的.看到这里,您也许马上想到用模板导出!而且.NET中自带有这个组件:Microsoft.Office.Interop.Word,暂且可以满足需求吧.但这个组件也是有局限性的,例如客户端必须装 office组件,而且编码复杂度高.最麻烦的需求是后面那个-

  • 在Windows系统下使用PHP生成Word文档的教程

    准备工作 首先,请确保在你的Windows系统中已经安装并配置好了一个典型的WAMP环境.由于Interop纯粹是一个Windows的特性,我们将在Windows平台下搭建Apache和PHP.在这个实例中,我使用了EasyPHP 14.1,这款软件安装和配置都十分容易. 接下来,我们要安装Microsoft Office.版本不是严格要求的.我正在使用的是Office2013专业版,但是任何2007之后的Office版本都应该可以使用. 我们然后需要去确保开发Interop应用(又被称作PIA

  • C#实现通过模板自动创建Word文档的方法

    本文实例讲述了C#实现通过模板自动创建Word文档的方法,是非常实用的技巧.分享给大家供大家参考.具体实现方法如下: 引言:前段时间有项目要用c#生成Word格式的计算报告,通过网络查找到很多内容,但是都很凌乱,于是自己决定将具体的步骤总结整理出来,以便于更好的交流和以后相似问题可以迅速的解决! 现通过具体的示例演示具体的步骤:   第一步,制作模板   1.新建一个文档,设置文档内容. 2.在相应位置插入书签:将鼠标定位到要插入书签的位置,点击"插入">"书签&quo

  • 使用Python 自动生成 Word 文档的教程

    当然要用第三方库啦 :) 使用以下命令安装: pip install python-docx 使用该库的基本步骤为: 1.建立一个文档对象(可自动使用默认模板建立,也可以使用已有文件). 2.设置文档的格式(默认字体.页面边距等). 3.在文档对象中加入段落文本.表格.图像等,并指定其样式. 4.保存文档. 注:本库仅支持生成Word2007以后版本的文档类型,即扩展名为.docx 的. 下面分步介绍其基本使用方法: 步骤一: from docx import Document doc = Do

  • Python自动化之批量生成含指定数据的word文档

    目录 一.需求说明 二.开始动手动脑 三.总结 一.需求说明 在平时工作当中,经常需要处理文件,特别是Word,处理Word时会遇一类比较常见的场景:文档中大部分文字固定不变,小部分内容需要修改. 这时我们会机械的重复打开.修改.保存文档等一系列操作,内容少还可勉强接受,内容一旦多了,心里难免会心浮气躁. 今天我要给大家介绍一个秘密武器-docxtpl开发包,有了这个只需写一份模板,其他的都交给电脑自己进行. 首先需要你的电脑安装好了Python环境,并且安装好了Python开发工具. 如果你还

  • Java生成word文档的示例详解

    目录 目标 依赖 模版 实体 代码 目标 依赖 <!-- poi工具类--> <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.12.0</version> </dependency> 模版 实体 实体类需要和模版内的动态字段对应 代码 @GetMapping(value =

  • 利用Java Apache POI 生成Word文档示例代码

    最近公司做的项目需要实现导出Word文档的功能,网上关于POI生成Word文档的例子很少,找了半天才在官网里找到个Demo,有了Demo一切就好办了. /* ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See

  • PHP生成word文档的三种实现方式

    最近工作遇到关于生成word的问题 现在总结一下生成word的三种方法. btw:好像只要是标题带PHP的貌似点击量都不是很高(哥哥我标题还是带上PHP了),不知道为什么,估计博客园上net技术大牛比较多吧,如果把java,.net,php比作程序员的女友,那么java是Oracle门下的大家闺秀,.net微软旗下的名门望族,PHP则是草根门下的山村野姑,这让我等PHP草民闷骚男情何以堪情何以堪..牢骚发完了,正式写吧 PHP生成word原理 利用windows下面的 com组件 利用PHP将内

  • JSP生成WORD文档,EXCEL文档及PDF文档的方法

    本文实例讲述了JSP生成WORD文档,EXCEL文档及PDF文档的方法.分享给大家供大家参考,具体如下: 在web-oa系统中,公文管理好象不可或缺,有时需要从数据库中查询一些数据以某种格式输出来,并以word文档的形式展现,有时许多word文档保存到数据库中的某个表的Blob字段里,服务器再把保存在Blob字段中的图片文件展现给用户.通过网上查找发现很少有关于此类的文章,现在整理起来供大家参考. 1 在client端直接生成word文档 在jsp页面上生成word文档非常简单,只需把conte

随机推荐