1.导入依赖

implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '3.17'
implementation group: 'org.apache.xmlbeans', name: 'xmlbeans', version: '3.1.0'
implementation 'javax.xml.stream:stax-api:1.0'
implementation 'com.fasterxml:aalto-xml:1.2.2'

工具类

package com.example.exportfile;import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Canvas;
import android.graphics.pdf.PdfDocument;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;public class SheetHelper {static String TAG = "<<< SheetHelper >>>";/*** 导出Excel** @param title           标题,配合 DeviceInfo 按需传入* @param listData        导出行数据* @param fileDir         导出文件夹* @param fileName        导出文件名* @param context         activity上下文* @param fileNameReplace 文件名称存在时,是否需要替换* @return*/public static boolean exportExcel(String[] title, List<DeviceInfo> listData, String fileDir, String fileName, Context context, boolean fileNameReplace) {if (TextUtils.isEmpty(fileDir) || TextUtils.isEmpty(fileName) || listData == null) {Log.e(TAG, " 导出" + "入参不合规");return false;}try {// 创建excel xlsx格式Workbook wb = new XSSFWorkbook();// 创建工作表Sheet sheet = wb.createSheet();//创建行对象Row row = sheet.createRow(0);// 设置有效数据的行数和列数int colNum = title.length;   // String[] title = {"序号", "设备号", "手机品牌", "最新位置", "换机换卡次数", "应用安装数量", "卸载应用次数", "违规app个数"};for (int i = 0; i < colNum; i++) {sheet.setColumnWidth(i, 20 * 256);  // 显示20个字符的宽度  列宽Cell cell1 = row.createCell(i);//第一行cell1.setCellValue(title[i]);}// 导入数据for (int rowNum = 0; rowNum < listData.size(); rowNum++) {// 之所以rowNum + 1 是因为要设置第二行单元格row = sheet.createRow(rowNum + 1);// 设置单元格显示宽度row.setHeightInPoints(28f);// DeviceInfo 这个是我的业务类,这个是根据业务来进行填写数据DeviceInfo bean = listData.get(rowNum);for (int j = 0; j < title.length; j++) {Cell cell = row.createCell(j);//要和title[]一一对应switch (j) {case 0://序号cell.setCellValue(bean.getRow());break;case 1://设备idcell.setCellValue(bean.getDeviceId());break;case 2://手机品牌cell.setCellValue(bean.getPhoneBrand());break;case 3://最新位置cell.setCellValue(bean.getLatestLocation());break;case 4://换机换卡次数cell.setCellValue(bean.getChangeSum());break;case 5://应用安装数量cell.setCellValue(bean.getInstallAppSum());break;case 6://卸载应用次数cell.setCellValue(bean.getUninstallAppSum());break;case 7://违规app个数cell.setCellValue(bean.getViolationAppSum());break;}}}String s = Environment.getExternalStorageDirectory() + "/" + fileDir;
//            String mSDCardFolderPath = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + "/" + fileDir;File dir = new File(s);//判断文件是否存在if (!dir.exists()) {//不存在则创建dir.mkdirs();}File excel = new File(dir, fileName + ".xlsx");if (!excel.exists()) {excel.createNewFile();} else {if (fileNameReplace) {//String newFileName = getNewFileName(getFiles(dir.getPath(), new ArrayList<>()), excel.getPath());String newFileName = getXlsxNewFileName(excel);excel = new File(newFileName);excel.createNewFile();}}Log.e(TAG, " 导出路径" + excel.getPath().toString());FileOutputStream fos = new FileOutputStream(excel);wb.write(fos);wb.close();fos.flush();fos.close();return true;} catch (IOException e) {Log.e("ExpressExcle", "exportExcel", e);return false;}}/*** 导入excel** @param fileName 本地文件路径*/public static List<String> readExcel(String fileName) {Log.d(TAG, "!!!导入路径!!!" + fileName);if (TextUtils.isEmpty(fileName)) {Log.d(TAG, "!!!导入失败!!!" + " 路径为空 ");return null;}try {InputStream inputStream = new FileInputStream(fileName);Workbook workbook;if (fileName.endsWith(".xls")) {workbook = new HSSFWorkbook(inputStream);} else if (fileName.endsWith(".xlsx")) {workbook = new XSSFWorkbook(inputStream);} else {Log.d(TAG, "!!!导入失败!!!" + " 文件格式错误 ");return null;}int numberOfSheets = workbook.getNumberOfSheets();List<String> strings = new ArrayList<>();for (int u = 0; u < numberOfSheets; u++) {Sheet sheet = workbook.getSheetAt(u);//获取表int rowsCount = sheet.getPhysicalNumberOfRows();//获取行数int lastRowNum = sheet.getLastRowNum();//获取最后一行,,从0开始Log.d(TAG, "行数:" + (lastRowNum + 1));FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();for (int r = 0; r <= lastRowNum; r++) {String str = "";Row row = sheet.getRow(r);//拿到行对象if (row != null) {int physicalNumberOfCells = row.getPhysicalNumberOfCells();//获取该行可用的列数、short lastCellNum = row.getLastCellNum();//获取改行最后一列的列数int lastCell = lastCellNum;Log.d(TAG, "导入  第" + (r + 1) + "行最后一列:" + lastCell);for (int i = 0; i < lastCell; i++) {CellValue v0 = formulaEvaluator.evaluate(row.getCell(i));//获取单元格对象if (v0 != null) {CellType cellTypeEnum = v0.getCellTypeEnum();if (cellTypeEnum.getCode() == 1) {//文本类型str += v0.getStringValue() + "&&";} else if (cellTypeEnum.getCode() == 0) {//整数,小数类型
//                                    double numberValue = v0.getNumberValue();String stringValue = new NumberEval(v0.getNumberValue()).getStringValue();str += stringValue + "&&";} else {//其他类型,暂时不解析}}}Log.d(TAG, "导入  第" + (r + 1) + "行  内容:" + str);strings.add(str);} else {Log.d(TAG, "第 " + (r + 1) + " 行没有可用表格,跳过");continue;}}}workbook.close();return strings;} catch (IOException e) {e.printStackTrace();return null;}}/*** 导出PDF** @param view            要导出的view,如果view高度过高(超过一屏的高度),在改view外部套一层Scrollview即可* @param fileDir         导出文件夹* @param fileName        导出文件名称* @param fileNameReplace 文件名称存在时,是否需要替换* @return*/public static boolean createPdfFromView(View view, String fileDir, String fileName, boolean fileNameReplace) {try {if (view == null || fileDir == null || fileName == null) {Log.e(TAG, "导出PDF" + "入参为空");return false;}String s = Environment.getExternalStorageDirectory() + "/" + fileDir;
//            String mSDCardFolderPath = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + "/" + fileDir;File dir = new File(s);//判断文件是否存在if (!dir.exists()) {//不存在则创建dir.mkdirs();}File pdfFile = new File(dir, fileName + ".PDF");if (!pdfFile.exists()) {pdfFile.createNewFile();} else {if (fileNameReplace) {String newFileName = getPDFNewFileName(pdfFile);pdfFile = new File(newFileName);pdfFile.createNewFile();}}PdfDocument document = new PdfDocument();//页对象PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(view.getWidth(),view.getHeight(),1).create();// 开始页PdfDocument.Page page = document.startPage(pageInfo);//绘制页Canvas canvas = page.getCanvas();view.draw(canvas);//结束页document.finishPage(page);//TODO  需要的话,增加更多页//导出文档FileOutputStream os = null;Log.i(TAG, "导出PDF" + " 开始导出,导出路径:" + pdfFile);os = new FileOutputStream(pdfFile);document.writeTo(os);os.close();Log.i(TAG, "导出PDF" + " 导出成功");document.close();return true;} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();return false;}}private static String getXlsxNewFileName(File file) {if (file.exists()) {String newPath = file.getPath().substring(0, file.getPath().length() - 5) + "(1).xlsx";return getXlsxNewFileName(new File(newPath));} else {return file.getPath();}}private static String getPDFNewFileName(File file) {if (file.exists()) {String newPath = file.getPath().substring(0, file.getPath().length() - 4) + "(1).PDF";return getPDFNewFileName(new File(newPath));} else {return file.getPath();}}static class DeviceInfo {private String row;//行private String deviceId;//设备idprivate String phoneBrand;//手机品牌private String latestLocation;//最新位置private String changeSum;//换机换卡次数private String installAppSum;//应用安装数量private String uninstallAppSum;//卸载应用次数private String violationAppSum;//违规app个数public DeviceInfo() {}public String getRow() {return row;}public void setRow(String row) {this.row = row;}public String getDeviceId() {return deviceId;}public void setDeviceId(String deviceId) {this.deviceId = deviceId;}public String getPhoneBrand() {return phoneBrand;}public void setPhoneBrand(String phoneBrand) {this.phoneBrand = phoneBrand;}public String getLatestLocation() {return latestLocation;}public void setLatestLocation(String latestLocation) {this.latestLocation = latestLocation;}public String getChangeSum() {return changeSum;}public void setChangeSum(String changeSum) {this.changeSum = changeSum;}public String getInstallAppSum() {return installAppSum;}public void setInstallAppSum(String installAppSum) {this.installAppSum = installAppSum;}public String getUninstallAppSum() {return uninstallAppSum;}public void setUninstallAppSum(String uninstallAppSum) {this.uninstallAppSum = uninstallAppSum;}public String getViolationAppSum() {return violationAppSum;}public void setViolationAppSum(String violationAppSum) {this.violationAppSum = violationAppSum;}}
}

2.导出 xls   需要异步调用

核心代码:
boolean isSuccess = SheetHelper.exportExcel(title, deviceInfos, "应用痕迹导出文件夹", "导出测试", MainActivity.this, true);示例:List<SheetHelper.DeviceInfo> deviceInfos = new ArrayList<>();for (int i = 0; i < 20; i++) {SheetHelper.DeviceInfo deviceInfo = new SheetHelper.DeviceInfo();deviceInfo.setRow(String.valueOf(i + 1));//序号deviceInfo.setDeviceId("1531359236" + i);//设备iddeviceInfo.setPhoneBrand("华为" + i);//手机品牌deviceInfo.setLatestLocation("北京" + i);//最新位置deviceInfo.setChangeSum(String.valueOf(i));//换机换卡次数deviceInfo.setInstallAppSum(String.valueOf(i));//应用安装数量deviceInfo.setUninstallAppSum(String.valueOf(i));//卸载应用次数deviceInfo.setViolationAppSum(String.valueOf(i));//违规app个数deviceInfos.add(deviceInfo);}try {String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};int permission = ActivityCompat.checkSelfPermission(MainActivity.this, "android.permission.WRITE_EXTERNAL_STORAGE");if (permission != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_STORAGE, REQUEST_CODE);} else {
//                                boolean isSuccess = SheetHelper.exportExcel(phonebillExpressBeans, "应用痕迹导出文件夹", "导出测试", MainActivity.this);String[] title = {"序号", "设备号", "手机品牌", "最新位置", "换机换卡次数", "应用安装数量", "卸载应用次数", "违规app个数"};boolean isSuccess = SheetHelper.exportExcel(title, deviceInfos, "应用痕迹导出文件夹", "导出测试", MainActivity.this, true);runOnUiThread(new Runnable() {@Overridepublic void run() {if (isSuccess) {Toast.makeText(MainActivity.this, "导出成功", Toast.LENGTH_SHORT).show();} else {Toast.makeText(MainActivity.this, "导出失败", Toast.LENGTH_SHORT).show();}}});}} catch (Exception e) {e.printStackTrace();}}}).start();

3.导入  需要异步调用

首先调用系统文件管理器Intent intent = new Intent(Intent.ACTION_GET_CONTENT);intent.setType("*/*");//设置类型,我这里是任意类型,任意后缀的可以这样写。intent.addCategory(Intent.CATEGORY_OPENABLE);startActivityForResult(intent, 1000);接受管理器选中的文件@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);try {if (resultCode == Activity.RESULT_OK && requestCode == 1000) {Uri uri = data.getData();//得到uri,后面就是将uri转化成file的过程。String absolutePath = FileChooseUtil.uriToPath(this, uri);Log.d("选择了文件", "文件路径:" + absolutePath);new Thread(new Runnable() {@Overridepublic void run() {List<String> strings = SheetHelper.readExcel(absolutePath);runOnUiThread(new Runnable() {@Overridepublic void run() {if (strings != null) {String str = "";for (String string : strings) {String[] split = string.split("&&");for (String s : split) {Log.i("拿到数据", s);str += s;}str += "\n";}mTv_content.setText(str);Toast.makeText(MainActivity.this, "导入成功", Toast.LENGTH_SHORT).show();} else {Toast.makeText(MainActivity.this, "导入失败", Toast.LENGTH_SHORT).show();}}});}}).start();}} catch (Exception e) {Toast.makeText(MainActivity.this, "导入异常", Toast.LENGTH_SHORT).show();e.printStackTrace();}}

产考:

Android 系统文件浏览器_钟情短发姑娘的博客-CSDN博客

4.注意:

需要读写权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

高版本动态申请权限

String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
int permission = ActivityCompat.checkSelfPermission(this, "android.permission.WRITE_EXTERNAL_STORAGE");
if (permission != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, 1);
} else {
//logic
}

Android 10  有私密文件策略。解决:

res下新建xml文件夹,新建文件file_paths,文件内容如下

<resources><paths><root-pathname="root"path="" /><files-pathname="files"path="" /><cache-pathname="cache"path="" /><external-pathname="external"path="" /><external-files-pathname="external_file_path"path="" /><external-cache-pathname="external_cache_path"path="" /></paths>
</resources>

manifest  application 注册fileprovider

<providerandroid:name="androidx.core.content.FileProvider"android:authorities="cn.xy.phonebilladmin.fileProvider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" />
</provider>

sdk 29以上 允许根目录新建文件

application 加上

android:requestLegacyExternalStorage="true"

Android 导入导出excel xls、xlsx相关推荐

  1. DevExpress 自带的导出EXCEL xls xlsx

    SaveFileDialog saveFileDialog = new SaveFileDialog();                 saveFileDialog.Title = "导 ...

  2. ASP.NET Core 导入导出Excel xlsx 文件

    ASP.NET Core 使用EPPlus.Core导入导出Excel xlsx 文件,EPPlus.Core支持Excel 2007/2010 xlsx文件导入导出,可以运行在Windows, Li ...

  3. csv和excel php 解析_PHP 高效导入导出Excel(csv)方法之fgetcsv()和fputcsv()函数

    CSV,是Comma Separated Value(逗号分隔值)的英文缩写,通常都是纯文本文件. 一.CSV数据导入函数fgetcsv() fgetcsv() 函数从文件指针中读入一行并解析 CSV ...

  4. mvc npoi导出excel ajax,ASP.Net MVC利用NPOI导入导出Excel

    因近期项目遇到所以记录一下: 首先导出Excel: 首先引用NPOI包 http://pan.baidu.com/s/1i3Fosux (Action一定要用FileResult) /// /// 批 ...

  5. 让 .Net 更方便的导入导出 Excel

    让 .Net 更方便的导入导出Excel Intro 因为前一段时间需要处理一些 excel 数据,主要是导入/导出操作,将 Excel 数据转化为对象再用程序进行处理和分析,没有找到比较满意的库,于 ...

  6. java导入导出excel文件

    前言:该文章使用java集成poi来操作excel文件,此处只对poi相关api进行代码编写,对于poi的理论性知识,可在学习完这篇文章后,自行百度学习.建议大家跟着文章敲一遍代码. 创建一个mave ...

  7. 使用EasyPoi导入导出Excel

    easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言( ...

  8. 使用easypoi导入导出excel,SSM和SpringBoot通用代码

    easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板语言(熟悉 ...

  9. java 导入excel工具类_java Excel工具类,导入导出Excel数据

    java Excel工具类,导入导出Excel数据,导入数据对合并表格有判断获取数据: 导出数据到Excel,Excel文件不存在会创建. 使用的是poi处理,兼容Excel. 对反射不够理解,目前先 ...

  10. java jdbc excel_详解poi+springmvc+springjdbc导入导出excel实例

    工作中常遇到导入导出excel的需求,本獂有一简答实例与大家分享. 废话不多说, 1.所需jar包: 2.前端代码: ieport.jsp: 导入\导出页面 function exportFile() ...

最新文章

  1. C++ 泛型编程 -- 函数模版
  2. 数据蒋堂 | JOIN简化 - 意义总结
  3. 数値の切捨て、切り上げ、四捨五入
  4. 初级图像混合——线性混合操作
  5. 关于Markdown编辑器添加使用锚点的问题
  6. python数据结构剑指offer-替换空格
  7. MySQL从查找数据库表到删除全过程
  8. 看各行从业人员给你一一点透的黑幕!亮点惊人!
  9. xshell5和xftp5安装教程
  10. 分枝定界法(Branch-and-Cut)
  11. 《非洲归来 不必远方》读后感
  12. C语言 找数字,用(折半查找法或二分查找法)
  13. 实验02-微信公众号编辑模式应用
  14. 谷歌html弹出ie页面,HTML用JS识别浏览器,IE内核则调用谷歌打开指定链接
  15. springboot+vue+安卓二手交易平台源码
  16. Go秒杀系统——RabbitMQ核心概念与工作模式
  17. java.sql.SQLException: unkow jdbc driver : jdbc:oscar:@127.0.0.1:2003/OSRDB
  18. 人行征信上贷款余额指的是什么?(图文)
  19. 物化视图是否可以exp导出_ORACLE EXP(导出)/IMP(导入)的使用详解
  20. Jfinal项目提供接口

热门文章

  1. vscode下载安装及中文配置
  2. rs 华为hcip 课件下载_华为路由与交换hcip最新题库
  3. [架构之路-42]:目标系统 - 系统软件 - Linux下的网络通信-2-无线局域网WIFI原理、WIFI与3G/4G/以太网/蓝牙的协议转换
  4. wifi发射功率各国标准_智能插座背后的两种无线协议——WiFi与ZigBee
  5. 国密算法(SM2)简介及SM2生成秘钥
  6. 基于Word2vec文本聚类
  7. 加密卡华为怎么模拟_华为手机NFC模拟加密的门禁卡详细教程
  8. 计算机专业课考研八月份复习,2016考研:计算机专业暑期复习攻略
  9. 飞思卡尔单片机CAN模块的物理特性的示波器观察
  10. python导入鸢尾花数据集_python鸢尾花数据集的分类问题 -- 逻辑回归问题研究