最近项目要实现一个功能, 将android app里面的数据库导成Excel表格 , 并将Excel表格通过蓝牙发送到其他设备上.
先看看界面 , 图二 为文件管理器里看到的文件。
大概的功能图片上都已经体现了, 下面来讲讲实现的思路
1. 数据的录入及保存到数据库 , 数据库我用的是郭神的litepal , 郭神也是最近刚更新到了2.0版本 , 大家有兴趣的可以看看他的博客.
2. 把数据库通过jxl.jar 转换成Excel表格,
3. 将Excel表格用蓝牙发送到其他设备.
下面看代码 MainActivity.class
package com.example.admin.litepaltoexcel; import android.Manifest; import android.annotation.SuppressLint; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.os.StrictMode; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import com.example.admin.litepaltoexcel.bean.Product; import com.example.admin.litepaltoexcel.dao.ProductDao; import com.example.admin.litepaltoexcel.excel.ExcelUtils; import org.litepal.util.LogUtil; import java.io.File; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; public class MainActivity extends AppCompatActivity { private static final int MY_PERMISSIONS_REQUEST = 111; private static final int CHECK_PERMISSION = 222; private String[] title = {"ID","船只名称", "时间", "产品名称", "产品批次", "捕捞区域", "纬度", "经度", "备注说明"}; private EditText edtBoatName; private EditText edtDateTime; private EditText edtProductName; private EditText edtProductBatch; private EditText edtArea; private EditText edtLat; private EditText edtLon; private EditText edtNote; private Button mSaveBtn; private String[] saveData; private ProductDao mProductDao; private File file; private ArrayList> bill2List; private String mFileName; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewsById(); mProductDao = new ProductDao(); bill2List = new ArrayList >(); getPermissions(); initPhotoError(); } private void initPhotoError(){ // android 7.0系统解决获取文件和拍照的问题 StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { builder.detectFileUriExposure(); } } private void getPermissions() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS) == PackageManager.PERMISSION_GRANTED) { //获取权限后 才能读写数据库 } else { ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS}, CHECK_PERMISSION); } } private void findViewsById() { edtBoatName = (EditText) findViewById(R.id.edt_boatName); edtDateTime = (EditText) findViewById(R.id.edt_dateTime); edtProductName = (EditText) findViewById(R.id.edt_productName); edtProductBatch = (EditText) findViewById(R.id.edt_productBatch); edtArea = (EditText) findViewById(R.id.edt_area); edtLat = (EditText) findViewById(R.id.edt_Lat); edtLon = (EditText) findViewById(R.id.edt_Lon); edtNote = (EditText) findViewById(R.id.edt_note); mSaveBtn = (Button) findViewById(R.id.btn_save); String time = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date()); String times = new SimpleDateFormat("yyyy_MM_dd").format(new Date()); edtDateTime.setText(time); edtProductBatch.setText(times+"_aaa"); mSaveBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { saveDB(); } }); } private void saveDB() { saveData = new String[]{edtBoatName.getText().toString().trim(), edtDateTime.getText().toString().trim(), edtProductName.getText().toString().trim(), edtProductBatch.getText().toString().trim(), edtArea.getText().toString().trim(), edtLat.getText().toString().trim(), edtLon.getText().toString().trim(), edtNote.getText().toString().trim()}; if (canSave(saveData)) { Product product = new Product(); product.setBoatName(edtBoatName.getText().toString().trim()); product.setDateTime(edtDateTime.getText().toString().trim()); product.setProductName(edtProductName.getText().toString().trim()); product.setProductBatch(edtProductBatch.getText().toString().trim()); product.setArea(edtArea.getText().toString().trim()); product.setLat(edtLat.getText().toString().trim()); product.setLon(edtLon.getText().toString().trim()); product.setNote(edtNote.getText().toString().trim()); boolean save = product.save(); // mProductDao.save(product); int id = product.getId(); Log.d("tag", id + ""); if (save){ Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(MainActivity.this, "保存失败", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(MainActivity.this, "请填写任意一项内容", Toast.LENGTH_SHORT).show(); } } private boolean canSave(String[] data) { boolean isOk = false; for (int i = 0; i < data.length; i++) { if (i > 0 && i < data.length) { if (!TextUtils.isEmpty(data[i])) { isOk = true; } } } return isOk; } /** * ----------------------------------------LItepal to Excel--------------------------------------------------------------- **/ //当客户点击MENU按钮的时候,调用该方法 @Override public boolean onCreateOptionsMenu(Menu menu) { menu.add(0, 1, 1, "查看数据库"); menu.add(0, 2, 2, "保存到Excel"); menu.add(0, 3, 3, "蓝牙发送Excel数据"); return super.onCreateOptionsMenu(menu); } //当客户点击菜单当中的某一个选项时,会调用该方法 @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == 1) { Intent intent = new Intent(this , BillListActivity.class); startActivity(intent); }else if (item.getItemId() == 2) { Log.d("TAG", "保存到Excel"); List productList = mProductDao.findAllByLimit(); if (productList.size()>0){ createExcel(); }else { Toast.makeText(MainActivity.this, "数据库无内容", Toast.LENGTH_SHORT).show(); } } else if (item.getItemId() == 3) { Log.d("TAG", "蓝牙发送Excel数据"); checkBluetoothPermission(); } return super.onOptionsItemSelected(item); } //创建Excel表格 并保存数据到Excel表格中 @SuppressLint("SimpleDateFormat") private void createExcel() { //创建文件 file = new File(getSDPath() + "/Trace"); makeDir(file); //创建Excel表格 mFileName = file.toString() + "/bill.xls"; ExcelUtils.initExcel(file.toString() + "/bill.xls", title); //将数据写入Excel表格 ExcelUtils.writeObjListToExcel(getBillData(), getSDPath() + "/Trace/bill.xls", this); } private ArrayList > getBillData() { List productList = mProductDao.findAllByLimit(); for (Product product : productList) { ArrayList beanList = new ArrayList (); beanList.add(product.getId()+""); beanList.add(product.getBoatName()); beanList.add(product.getDateTime()); beanList.add(product.getProductName()); beanList.add(product.getProductBatch()); beanList.add(product.getArea()); beanList.add(product.getLat()); beanList.add(product.getLon()); beanList.add(product.getNote()); bill2List.add(beanList); } return bill2List; } public static void makeDir(File dir) { if (!dir.getParentFile().exists()) { makeDir(dir.getParentFile()); } dir.mkdir(); } public String getSDPath() { File sdDir = null; boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); if (sdCardExist) { sdDir = Environment.getExternalStorageDirectory(); } String dir = sdDir.toString(); return dir; } /***----------------------------蓝牙发送Excel文件------------------------------------------------------------------*/ private void connectBluetooth() { String dir = getSDPath() + "/Trace/bill.xls"; //mFileName File file = new File(dir); if(null==file || !file.exists()){ Toast.makeText(this, "Excel文件不存在", Toast.LENGTH_SHORT).show(); return; } Intent intent = new Intent(); intent.setAction(Intent.ACTION_SEND); // intent.setType("application/octet-stream"); intent.setType("*/*"); // intent.setClassName("com.android.bluetooth" , "com.android.bluetooth.opp.BluetoothOppLauncherActivity"); // intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile( new File("/sdcard/20095111013295162.jpg"))); intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile( new File(dir))); startActivity(intent); } //校验蓝牙权限 private void checkBluetoothPermission() { if (Build.VERSION.SDK_INT >= 23) { //校验是否已具有模糊定位权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { //具有权限 connectBluetooth(); } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, MY_PERMISSIONS_REQUEST); } } else { //系统不高于6.0直接执行 connectBluetooth(); } } // 对返回值进行处理,类似于startActivityForResult方法: @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); doNext(requestCode, grantResults); } private void doNext(int requestCode, int[] grantResults) { if (requestCode == MY_PERMISSIONS_REQUEST) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { //同意权限 connectBluetooth(); } else { // 权限拒绝 // 下面的方法最好写一个跳转,可以直接跳转到权限设置页面,方便用户 // denyPermission(); Toast.makeText(this, "没有获取蓝牙权限,请先获取蓝牙权限", Toast.LENGTH_SHORT).show(); } }else if (requestCode == CHECK_PERMISSION //文件操作的权限 && grantResults.length == 3 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED && grantResults[2] == PackageManager.PERMISSION_GRANTED) { //获取权限后的操作 } } }
数据库转换用到的ExcelUtils.class
package com.example.admin.litepaltoexcel.excel; import android.content.Context; import android.widget.Toast; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import jxl.Workbook; import jxl.WorkbookSettings; import jxl.write.Label; import jxl.write.WritableCell; import jxl.write.WritableCellFormat; import jxl.write.WritableFont; import jxl.write.WritableSheet; import jxl.write.WritableWorkbook; import jxl.write.WriteException; public class ExcelUtils { public static WritableFont arial14font = null; public static WritableCellFormat arial14format = null; public static WritableFont arial10font = null; public static WritableCellFormat arial10format = null; public static WritableFont arial12font = null; public static WritableCellFormat arial12format = null; public final static String UTF8_ENCODING = "UTF-8"; public final static String GBK_ENCODING = "GBK"; public static void format() { try { arial14font = new WritableFont(WritableFont.ARIAL, 14, WritableFont.BOLD); arial14font.setColour(jxl.format.Colour.LIGHT_BLUE); arial14format = new WritableCellFormat(arial14font); arial14format.setAlignment(jxl.format.Alignment.CENTRE); arial14format.setBorder(jxl.format.Border.ALL, jxl.format.BorderLineStyle.THIN); arial14format.setBackground(jxl.format.Colour.VERY_LIGHT_YELLOW); arial10font = new WritableFont(WritableFont.ARIAL, 10, WritableFont.BOLD); arial10format = new WritableCellFormat(arial10font); arial10format.setAlignment(jxl.format.Alignment.CENTRE); arial10format.setBorder(jxl.format.Border.ALL, jxl.format.BorderLineStyle.THIN); arial10format.setBackground(jxl.format.Colour.LIGHT_BLUE); arial12font = new WritableFont(WritableFont.ARIAL, 12); arial12format = new WritableCellFormat(arial12font); arial12format.setBorder(jxl.format.Border.ALL, jxl.format.BorderLineStyle.THIN); } catch (WriteException e) { e.printStackTrace(); } } public static void initExcel(String fileName, String[] colName) { format(); WritableWorkbook workbook = null; try { File file = new File(fileName); if (!file.exists()) { file.createNewFile(); } workbook = Workbook.createWorkbook(file); WritableSheet sheet = workbook.createSheet("捕捞明细表", 0); sheet.addCell((WritableCell) new Label(0, 0, fileName, arial14format)); for (int col = 0; col < colName.length; col++) { sheet.addCell(new Label(col, 0, colName[col], arial10format)); } workbook.write(); } catch (Exception e) { e.printStackTrace(); } finally { if (workbook != null) { try { workbook.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } @SuppressWarnings("unchecked") public static <T> void writeObjListToExcel(List<T> objList, String fileName, Context c) { if (objList != null && objList.size() > 0) { WritableWorkbook writebook = null; InputStream in = null; try { WorkbookSettings setEncode = new WorkbookSettings(); setEncode.setEncoding(UTF8_ENCODING); in = new FileInputStream(new File(fileName)); Workbook workbook = Workbook.getWorkbook(in); writebook = Workbook.createWorkbook(new File(fileName), workbook); WritableSheet sheet = writebook.getSheet(0); for (int j = 0; j < objList.size(); j++) { ArrayListlist=(ArrayList ) objList.get(j); for (int i = 0; i < list.size(); i++) { sheet.addCell(new Label(i, j+1, list.get(i), arial12format)); } } writebook.write(); Toast.makeText(c, "保存Excel成功", Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); } finally { if (writebook != null) { try { writebook.close(); } catch (Exception e) { e.printStackTrace(); } } if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } } } public static Object getValueByRef(Class cls, String fieldName) { Object value = null; fieldName = fieldName.replaceFirst(fieldName.substring(0, 1), fieldName.substring(0, 1).toUpperCase()); String getMethodName = "get" + fieldName; try { Method method = cls.getMethod(getMethodName); value = method.invoke(cls); } catch (Exception e) { e.printStackTrace(); } return value; } }
重点是这两个类的代码 , 下面是整个项目的结构 ,数据库的代码就不展示了 , Excel的转换需要一个jxl.jar 包
整个项目完整的demo