欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】

程序员文章站 2022-06-02 18:59:07
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用Poi实现android中根据模板文件生成Word文档的功能。这里的模板文件是doc文件。如果模板文件是docx文件的话,请阅读下一篇文章《PoiDocxDemo【Android将表单数据生成Word文档的方案之二(基于Poi4 ......

版权声明:本文为haiyuking原创文章,转载请注明出处!

前言

使用poi实现android中根据模板文件生成word文档的功能。这里的模板文件是doc文件。如果模板文件是docx文件的话,请阅读下一篇文章《poidocxdemo【android将表单数据生成word文档的方案之二(基于poi4.0.0),目前只能java生成】

注意:

  • poi 4.0.0 is the first release to require java 8 or newer.

前期准备

1、下载poi相关jar包

官网下载地址:

如果windows系统,则下载zip文件;如果是linux系统则选择.tar.gz。

PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】

将下载后的压缩包解压,会得到以下文件。

PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】

文件(夹)名 作用
docs 文档(包括api文档和如何使用及版本信息)
lib doc功能实现依赖的包
ooxml-lib docx功能实现依赖的包
license  
notice  
poi-4.0.0.jar 基础类
poi-examples-4.0.0.jar 不明确,不知道什么作用
poi-excelant-4.0.0.jar excel功能实现
poi-ooxml-4.0.0.jar docx功能实现
poi-ooxml-schemas-4.0.0.jar docx功能实现相关类
poi-scratchpad-4.0.0.jar doc功能实现

 

2、制作docx模板或者doc模板文件

PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】

代码分析

1、可以看到doc和docx文件分别对应着组件hwpf和xwpf,而hwpf和xwpf则对应着poi-scratchpad和poi-ooxml。

PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】

官网地址:

使用步骤

一、项目组织结构图

PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】

PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】

注意事项:

1、  导入类文件后需要change包名以及重新import r文件路径

2、  values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

二、导入步骤

1、将poi相关jar文件导入项目中(demo采用的是module方式)

引用jar文件参考《【android studio安装部署系列】十七、android studio引用第三方库、jar、so、arr文件

注意:

解析doc文件,需要引用下面的jar文件:

  • poi-4.0.0.jar
  • poi-scratchpad-4.0.0.jar
  • libs目录下的commons-collections4-4.2.jar

PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】

 

2、在poilib和app的build.gradle文件中添加以下代码

poilib

apply plugin: 'com.android.library'

android {
    compilesdkversion 28



    defaultconfig {
        minsdkversion 16
        targetsdkversion 28
        versioncode 1
        versionname "1.0"

        testinstrumentationrunner "android.support.test.runner.androidjunitrunner"
    }

    buildtypes {
        release {
            minifyenabled false
            proguardfiles getdefaultproguardfile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    //poi
    compileoptions {
        sourcecompatibility javaversion.version_1_8
        targetcompatibility javaversion.version_1_8
    }

}

dependencies {
    implementation filetree(dir: 'libs', include: ['*.jar'])

    implementation 'com.android.support:appcompat-v7:28.0.0'
    testimplementation 'junit:junit:4.12'
    androidtestimplementation 'com.android.support.test:runner:1.0.2'
    androidtestimplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

    //poi=doc
    api files('libs/poi-4.0.0.jar')
    api files('libs/poi-scratchpad-4.0.0.jar')
    api files('libs/commons-collections4-4.2.jar')
}

app

apply plugin: 'com.android.application'

android {
    compilesdkversion 28
    defaultconfig {
        applicationid "com.why.project.poidemo"
        minsdkversion 16
        targetsdkversion 28
        versioncode 1
        versionname "1.0"
        testinstrumentationrunner "android.support.test.runner.androidjunitrunner"
    }
    buildtypes {
        release {
            minifyenabled false
            proguardfiles getdefaultproguardfile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    //poi
    compileoptions {
        sourcecompatibility javaversion.version_1_8
        targetcompatibility javaversion.version_1_8
    }
}

dependencies {
    implementation filetree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testimplementation 'junit:junit:4.12'
    androidtestimplementation 'com.android.support.test:runner:1.0.2'
    androidtestimplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    //poi
    implementation project(':poilib')
}

3、在poilib这个module中添加poiutils.java文件

PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】

4、将模板文件复制到项目的assets目录下

PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】

三、使用方法

1、根据doc模板生成doc文件的关键代码

mainactivity.java

package com.why.project.poidemo;

import android.content.context;
import android.os.bundle;
import android.support.v7.app.appcompatactivity;
import android.view.view;

import com.why.project.poilib.poiutils;

import java.io.file;
import java.io.ioexception;
import java.io.inputstream;
import java.util.hashmap;
import java.util.map;

public class mainactivity extends appcompatactivity {

    private context mcontext;

    @override
    protected void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        setcontentview(r.layout.activity_main);

        mcontext = this;

        //利用doc模板生成doc文件
        findviewbyid(r.id.btn_poi_doc).setonclicklistener(new view.onclicklistener() {
            @override
            public void onclick(view view) {
                try {
                    inputstream templetdocstream = getassets().open("请假单模板2.doc");

                    string targetdocpath = mcontext.getexternalfilesdir("poi").getpath() + file.separator + "请假单2.doc";//这个目录,不需要申请存储权限

                    map<string, string> datamap = new hashmap<string, string>();
                    datamap.put("$writedate$", "2018年10月14日");
                    datamap.put("$name$", "haiyuking");
                    datamap.put("$dept$", "移动开发组");
                    datamap.put("$leavetype$", "☑倒休 √年假 ✔事假 ☐病假 ☐婚假 ☐产假 ☐其他");
                    datamap.put("$leavereason$", "倒休一天。");
                    datamap.put("$leavestartdate$", "2018年10月14日上午");
                    datamap.put("$leaveenddate$", "2018年10月14日下午");
                    datamap.put("$leaveday$", "1");
                    datamap.put("$leaveleader$", "同意");
                    datamap.put("$leavedeptleaderimg$", "同意!");

                    poiutils.writetodoc(templetdocstream,targetdocpath,datamap);

                } catch (ioexception e) {
                    e.printstacktrace();
                }

            }
        });
    }
}

 

 poiutils.java

package com.why.project.poidemo.poi;

import org.apache.poi.hwpf.hwpfdocument;
import org.apache.poi.hwpf.usermodel.range;

import java.io.fileinputstream;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.io.inputstream;
import java.util.map;

/**
 * created by haiyuking
 * used poi工具类封装
 * 在使用poi写word doc文件的时候我们必须要先有一个doc文件才行,因为我们在写doc文件的时候是通过hwpfdocument来写的,
 * 而hwpfdocument是要依附于一个doc文件的。所以通常的做法是我们先在硬盘上准备好一个内容空白的doc文件,然后建立一个基于该空白文件的hwpfdocument。
 * 之后我们就可以往hwpfdocument里面新增内容了,然后再把它写入到另外一个doc文件中,这样就相当于我们使用poi生成了word doc文件。
 */
public class poiutils {

    /**
     * 生成一个doc文件
     * @param templetdocpath  模板文件的完整路径
     * @param targetdocpath 生成的目标文件的完整路径
     * @param datamap 替换的数据*/
    public static void writetodoc(string templetdocpath, string targetdocpath, map<string,string> datamap){
        try
        {
            //得到模板doc文件的hwpfdocument对象
            inputstream in = new fileinputstream(templetdocpath);
            writetodoc(in,targetdocpath,datamap);
        }
        catch(ioexception e)
        {
            e.printstacktrace();
        }
    }

    /**
     * 生成一个doc文件,主要用于直接读取asset目录下的模板文件,不用先复制到sd卡中
     * @param templetdocinstream  模板文件的inputstream
     * @param targetdocpath 生成的目标文件的完整路径
     * @param datamap 替换的数据*/
    public static void writetodoc(inputstream templetdocinstream, string targetdocpath, map<string,string> datamap){
        try
        {
            //得到模板doc文件的hwpfdocument对象
            hwpfdocument hdoc = new hwpfdocument(templetdocinstream);
            // 获取word文本内容,整个文本
            range range = hdoc.getrange();
            // 替换文本内容,将自定义的$xxx$替换成实际文本
            for(map.entry<string, string> entry : datamap.entryset())
            {
                range.replacetext(entry.getkey(), entry.getvalue());
            }
            //写到另一个文件中
            fileoutputstream out = new fileoutputstream(targetdocpath, true);
            //把doc输出到输出流中
            hdoc.write(out);
            out.close();
            templetdocinstream.close();
        }
        catch(ioexception e)
        {
            e.printstacktrace();
        }
        catch(exception e)
        {
            e.printstacktrace();
        }
    }

}

2、效果

生成的文件路径:内部存储——android——data——com.why.project.poidemo——files——poi——请假单2.doc

PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】

混淆配置

参考资料

android使用apachepoi组件读写worddoc和docx文件

poi官网

android中使用poi加载与显示word文档

poi用addpicture插入图片到word里面无法显示

使用poi读写word doc文件

android中使用poi加载与显示word文档

项目demo下载地址

https://github.com/haiyuking/poidemo