From 3c5588b35ec3f3c905b66af68c4b8e2bff35ff53 Mon Sep 17 00:00:00 2001 From: xiaowusky Date: Mon, 22 May 2023 13:49:21 +0800 Subject: [PATCH] desc:export excel fun --- app/build.gradle | 19 +- .../example/myapplication/MainActivity.java | 31 +- .../example/myapplication/utils/ExcelUtils.kt | 409 ++++++++++++++++++ .../example/myapplication/utils/PathUtils.kt | 41 ++ .../example/myapplication/xls/ColumnObject.kt | 6 + .../example/myapplication/xls/Constants.kt | 52 +++ .../com/example/myapplication/xls/Demo.kt | 3 + .../myapplication/xls/ExcelLabelBean.kt | 3 + library-ijkplayer/build.gradle | 18 +- library-push/build.gradle | 18 +- 10 files changed, 550 insertions(+), 50 deletions(-) create mode 100644 app/src/main/java/com/example/myapplication/utils/ExcelUtils.kt create mode 100644 app/src/main/java/com/example/myapplication/utils/PathUtils.kt create mode 100644 app/src/main/java/com/example/myapplication/xls/ColumnObject.kt create mode 100644 app/src/main/java/com/example/myapplication/xls/Constants.kt create mode 100644 app/src/main/java/com/example/myapplication/xls/Demo.kt create mode 100644 app/src/main/java/com/example/myapplication/xls/ExcelLabelBean.kt diff --git a/app/build.gradle b/app/build.gradle index 54ea2e1..2f932a2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,7 +1,7 @@ -apply plugin: 'com.android.application' +apply from: "${rootProject.rootDir}/buildCommon/commonLibConfig.gradle" +project.ext.setAppDefaultConfig project android { - compileSdkVersion 31 lintOptions { checkReleaseBuilds false @@ -11,11 +11,6 @@ android { } defaultConfig { applicationId "com.example.myapplication" - minSdkVersion 19 - targetSdkVersion 31 - versionCode 1 - versionName "1.0" - ndk { //设置支持的SO库架构(开发者可以根据需要,选择一个或多个平台的so) @@ -23,13 +18,6 @@ android { } } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } - viewBinding { enabled = true } @@ -58,5 +46,8 @@ dependencies { implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' implementation 'androidx.lifecycle:lifecycle-reactivestreams:2.4.1' implementation project(path: ':library-ijkplayer') + implementation project(path: ':library-serialPort') + //添加excel + implementation rootProject.ext.dependencies.jxl annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.0.0' } diff --git a/app/src/main/java/com/example/myapplication/MainActivity.java b/app/src/main/java/com/example/myapplication/MainActivity.java index 3860ec9..3ea073a 100644 --- a/app/src/main/java/com/example/myapplication/MainActivity.java +++ b/app/src/main/java/com/example/myapplication/MainActivity.java @@ -25,9 +25,14 @@ import android.widget.TextView; import android.widget.Toast; import com.example.myapplication.player.ProVideoActivity; +import com.example.myapplication.utils.ExcelUtils; +import com.example.myapplication.xls.Demo; import org.easydarwin.push.MediaStream; +import java.util.ArrayList; +import java.util.List; + import io.reactivex.Single; import io.reactivex.functions.Consumer; @@ -242,10 +247,28 @@ public class MainActivity extends AppCompatActivity { public void onUVCCamera(View view) { // Intent intent = new Intent(this, UVCActivity.class); - Intent intent = new Intent(this, ProVideoActivity.class); - String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/mvtest.mp4"; - intent.putExtra("videoPath", path); - startActivity(intent); + + +// Intent intent = new Intent(this, ProVideoActivity.class); +// String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/mvtest.mp4"; +// intent.putExtra("videoPath", path); +// startActivity(intent); + + List> allData = new ArrayList<>(); + List row1 = new ArrayList<>(); + row1.add(new Demo("5.22")); + row1.add(new Demo("1")); + row1.add(new Demo("2")); + row1.add(new Demo("3")); + List row2 = new ArrayList<>(); + row2.add(new Demo("5.23")); + row2.add(new Demo("4")); + row2.add(new Demo("5")); + + allData.add(row1); + allData.add(row2); + + ExcelUtils.INSTANCE.writeStringListToExcelDemo(allData, this); } public void OnSaveRecord(View view) { diff --git a/app/src/main/java/com/example/myapplication/utils/ExcelUtils.kt b/app/src/main/java/com/example/myapplication/utils/ExcelUtils.kt new file mode 100644 index 0000000..655af6a --- /dev/null +++ b/app/src/main/java/com/example/myapplication/utils/ExcelUtils.kt @@ -0,0 +1,409 @@ +package com.example.myapplication.utils + +import android.content.Context +import android.text.TextUtils +import android.util.Log +import com.example.myapplication.xls.Constants +import com.example.myapplication.xls.Constants.COLUMN_NAME_MAP +import com.example.myapplication.xls.Demo +import com.example.myapplication.xls.ExcelLabelBean +import jxl.Workbook +import jxl.WorkbookSettings +import jxl.write.Label +import jxl.write.WritableCellFormat +import jxl.write.WritableFont +import jxl.write.WritableImage +import jxl.write.WritableWorkbook +import jxl.write.WriteException +import java.io.File +import java.io.FileInputStream +import java.io.InputStream + + +/** + * excel表格工具 + */ +object ExcelUtils { + private const val TAG: String = "ExcelUtils" + private const val UTF8_ENCODING = "UTF-8" + private var arial12format: WritableCellFormat? = null + private var ImageSize: Int = 0 + private val ImageSizeList = arrayListOf() + + private fun initExcel( + allRowsData: List>, + filePath: String, + sheetName: String + ) { + format() + + var workbook: WritableWorkbook? = null + try { + val file = File(filePath) + if (!file.exists()) { + file.createNewFile() + } + workbook = Workbook.createWorkbook(file) + val sheet = workbook.createSheet(sheetName, 0) + sheet.addCell(Label(0, 0, filePath, arial12format)) + ImageSize = 0 + ImageSizeList.clear() + for ((index, value) in allRowsData.withIndex()) { + ImageSizeList.add( + (allRowsData.get(index).get(8).excelLableContent.length - allRowsData.get(index) + .get(8).excelLableContent.replace("|", "").length) + 1 + ) + } + for (i in 0 until ImageSizeList.size) { + if (ImageSize < ImageSizeList.get(i)) { + ImageSize = ImageSizeList.get(i) + } + } + val columnNameMap = COLUMN_NAME_MAP + for (number in 0..ImageSize + 10) { + if (number <= 8) { + for ((index, value) in columnNameMap.withIndex()) { + if (index <= 8) { + sheet.addCell(Label(index, 0, value.excelName, arial12format)) + } + } + } else if (number > 8 && number <= ImageSize + 7) { + sheet.addCell(Label(number, 0, "", arial12format)) + } else if (number == ImageSize + 8) { + for ((index, value) in columnNameMap.withIndex()) { + if (index > 8) { + sheet.addCell( + Label( + index + ImageSize - 1, + 0, + value.excelName, + arial12format + ) + ) + } + } + } + } + workbook.write() + } catch (e: Exception) { + Log.e(TAG, "initExcel e==" + e.message) + } finally { + try { + workbook?.close() + } catch (e: Exception) { + Log.e(TAG, "initExcel e==" + e.message) + } + } + } + + private fun format() { + try { + val writableFont = WritableFont(WritableFont.ARIAL, 12) + arial12format = WritableCellFormat(writableFont) + arial12format?.setBorder(jxl.format.Border.ALL, jxl.format.BorderLineStyle.THIN) + } catch (exception: WriteException) { + Log.e(TAG, "format() e==" + exception.message) + } + + } + +// fun importSheet(context: Context): ArrayList { +// val inputStream: InputStream = +// context.resources.assets.open(Constants.ASSETS_PRESET_EXCEL_NAME) +// val book: Workbook = Workbook.getWorkbook(inputStream) +// try { +// +// val sheet = book.getSheet(0) +// val checkListTemplateBeans = ArrayList() +// for (i in 1 until sheet.rows) { +// val checkListTopic = CheckListTopic() +// //导入的Excel中第1列要是。检查主题‘ 这一项 +// checkListTopic.topicName = sheet.getCell(0, i).contents +// +// val checkObj = CheckObjType() +// //导入的Excel中第2列要是’检查对象‘ 这一项 +// checkObj.checkObj = sheet.getCell(1, i).contents +// +// val checkListTemplate = CheckListTemplate() +// //导入的Excel中第3列要是’检查项目‘ 这一项 +// checkListTemplate.inspectionItems = sheet.getCell(2, i).contents +// +// val checkContent = CheckContent() +// //导入的Excel中第4列要是’检查内容‘ 这一项 +// checkContent.inspectionContent = sheet.getCell(3, i).contents +// //导入的Excel中第5列要是’检查标准‘ 这一项 +// checkContent.inspectionRule = sheet.getCell(4, i).contents +// //导入的Excel中第6列要是’检查方法‘ 这一项 +// checkContent.inspectionFun = sheet.getCell(5, i).contents +// //导入的Excel中第7列要是’检查依据‘ 这一项 +// checkContent.inspectionBasis = sheet.getCell(6, i).contents +// +// val checkListTemplateBean = +// CheckListTemplateBean(checkListTopic, checkObj, checkListTemplate, checkContent) +// checkListTemplateBeans.add(checkListTemplateBean) +// } +// book.close(); +// return checkListTemplateBeans +// } catch (e: Exception) { +// Log.i(TAG, "importSheet e=" + e.message) +// } finally { +// book.close() +// inputStream.close() +// } +// return ArrayList() +// } + + + /** + * 获取一个对象的所有属性和值,包括其二级对象的属性和值 + */ + private fun readAllAttrs(any: Any): HashMap { + val hashMap: HashMap = HashMap() + try { + val javaClass = any.javaClass + val declaredFields = javaClass.declaredFields + for ((i, field) in declaredFields.iterator().withIndex()) { + field.isAccessible = true + val name = field.name + val valueAny = field[any] + hashMap[name] = valueAny + + //获取子对象的属性和值 + if (valueAny != null) { + val valueClass = valueAny.javaClass + val valueClassFields = valueClass.declaredFields + for (valueClassField in valueClassFields.iterator()) { + valueClassField.isAccessible = true + val valueClassFieldName = valueClassField.name + val valueClassFieldValue = valueClassField[valueAny] + hashMap[valueClassFieldName] = valueClassFieldValue + } + } + } + } catch (e: Exception) { + Log.e(TAG, "readAllAttrs() e==" + e.message) + } + + return hashMap; + } + + private fun makeDir(filePath: File) { + if (!filePath.parentFile.exists()) { + makeDir(filePath.parentFile) + } + filePath.mkdir() + } + + private fun deleteByPath(filePath: String) { + val file = File(filePath) + if (file.exists()) { + if (file.isFile || file.isDirectory) { + file.delete() + } + } + } + + private fun deleteExistFile(excelFilePath: String) { + val file = File(excelFilePath) + if (file.exists()) { + val files: Array = file.listFiles() + for (i in files.indices) { + deleteByPath(files[i].absolutePath) + } + } + } + + fun writeStringListToExcel( + allRowsData: List>, + context: Context + ): Boolean { + val fileName = PathUtils.getNowTimeFormat(PathUtils.DATE_TO_STRING_LONG_PATTERN) + ".xls" + Constants.EXCEL_EXPORT_NAME = fileName + val filePath = + PathUtils.getExternalStoragePath(context) + Constants.EXCEL_EXPORT_PATH + Constants.EXCEL_EXPORT_NAME + deleteExistFile(PathUtils.getExternalStoragePath(context) + Constants.EXCEL_EXPORT_PATH) + makeDir(File(PathUtils.getExternalStoragePath(context) + "/" + Constants.SAVE_EXPORT_EXCEL_PATH)) + + initExcel(allRowsData, filePath, Constants.SHEET_NAME) //需要写入权限 + + if (PathUtils.isListEmpty(allRowsData) || context == null) + return false + + var writebook: WritableWorkbook? = null + var inputStream: InputStream? = null + try { + val setEncode = WorkbookSettings() + setEncode.encoding = UTF8_ENCODING + inputStream = FileInputStream(File(filePath)) + val workbook = Workbook.getWorkbook(inputStream) + val file = File(filePath) + writebook = Workbook.createWorkbook(file, workbook) + val sheet = writebook.getSheet(0) +// for (number in 0..ImageSize+10) { + for ((row, item) in allRowsData.withIndex()) { + for ((colum, value) in item.withIndex()) { + if (value.isImage && !TextUtils.isEmpty(value.excelLableContent)) { + //这里value.excelLableContent 是图片在手机上的绝对地址,多个图片用|隔开 + if (colum == 8) { + val split = value.excelLableContent.split("|") + var tempColum = colum + for (imagePath in split) { + val imgFile = File(imagePath) + if (imgFile.exists()) { + val image = WritableImage( + tempColum.toDouble(), + (row + 1).toDouble(), + 1.0, + 1.0, + imgFile + ) + //设置行高 + sheet.setRowView(row + 1, 1700, false) + sheet.addImage(image) + tempColum++ + } + } + } else if (colum == 11) { + val split = value.excelLableContent.split("|") + var tempColum = colum + ImageSize - 1 + for (imagePath in split) { + val imgFile = File(imagePath) + if (imgFile.exists()) { + val image = WritableImage( + tempColum.toDouble(), + (row + 1).toDouble(), + 1.0, + 1.0, + imgFile + ) + //设置行高 + sheet.setRowView(row + 1, 1700, false) + sheet.addImage(image) + tempColum++ + } + } + } + } else if (colum <= 8) { + sheet.addCell(Label(colum, row + 1, value.excelLableContent, arial12format)) + } else if (colum > 8) { + sheet.addCell( + Label( + colum + ImageSize - 1, + row + 1, + value.excelLableContent, + arial12format + ) + ) + } +// } + } + } + writebook.write() + Log.i(TAG, "Excelel 写入成功") + return true + } catch (e: Exception) { + Log.e(TAG, "writeStringListToExcel() e==" + e.message) + } finally { + writebook?.close() + inputStream?.close() + } + + return false + } + +// fun transformExportData(records: MutableList): MutableList> { +// val allRowsData: MutableList> = java.util.ArrayList() +// +// for (checkListDetailItemBean in records) { +// val rowData: MutableList = ArrayList() +// val allAttrs = readAllAttrs(checkListDetailItemBean) +// for ((i, item) in COLUMN_NAME_MAP.withIndex()) { +// val obj = allAttrs[item.sqTabName] +// rowData.add(ExcelLabelBean(obj as String, item.isImage)) +// } +// allRowsData.add(rowData) +// } +// +// return allRowsData +// } + + private fun initExcelDemo( + allColumNames: List, + filePath: String, + sheetName: String + ) { + format() + + var workbook: WritableWorkbook? = null + try { + val file = File(filePath) + if (!file.exists()) { + file.createNewFile() + } + workbook = Workbook.createWorkbook(file) + val sheet = workbook.createSheet(sheetName, 0) + + allColumNames.forEachIndexed { index, s -> + sheet.addCell(Label(index, 0, s, arial12format)) + } + workbook.write() + } catch (e: Exception) { + Log.e(TAG, "initExcel e==" + e.message) + } finally { + try { + workbook?.close() + } catch (e: Exception) { + Log.e(TAG, "initExcel e==" + e.message) + } + } + } + + fun writeStringListToExcelDemo( + allRowsData: List>, + context: Context + ): Boolean { + val fileName = PathUtils.getNowTimeFormat(PathUtils.DATE_TO_STRING_LONG_PATTERN) + ".xls" + Constants.EXCEL_EXPORT_NAME = fileName + val filePath = + PathUtils.getExternalStoragePath(context) + Constants.EXCEL_EXPORT_PATH + Constants.EXCEL_EXPORT_NAME + deleteExistFile(PathUtils.getExternalStoragePath(context) + Constants.EXCEL_EXPORT_PATH) + makeDir(File(PathUtils.getExternalStoragePath(context) + "/" + Constants.SAVE_EXPORT_EXCEL_PATH)) + + val columNames = mutableListOf() + columNames.add("时间") + columNames.add("columNames1") + columNames.add("columNames2") + columNames.add("columNames3") + initExcelDemo(columNames, filePath, Constants.SHEET_NAME) //需要写入权限 + + if (PathUtils.isListEmpty(allRowsData) || context == null) + return false + + var writebook: WritableWorkbook? = null + var inputStream: InputStream? = null + try { + val setEncode = WorkbookSettings() + setEncode.encoding = UTF8_ENCODING + inputStream = FileInputStream(File(filePath)) + val workbook = Workbook.getWorkbook(inputStream) + val file = File(filePath) + writebook = Workbook.createWorkbook(file, workbook) + val sheet = writebook.getSheet(0) + for ((row, item) in allRowsData.withIndex()) { + item.forEachIndexed { index, demo -> + sheet.addCell(Label(index, row + 1, demo.content, arial12format)) + } + } + writebook.write() + Log.i(TAG, "Excelel 写入成功") + return true + } catch (e: Exception) { + Log.e(TAG, "writeStringListToExcel() e==" + e.message) + } finally { + writebook?.close() + inputStream?.close() + } + + return false + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/utils/PathUtils.kt b/app/src/main/java/com/example/myapplication/utils/PathUtils.kt new file mode 100644 index 0000000..a6198af --- /dev/null +++ b/app/src/main/java/com/example/myapplication/utils/PathUtils.kt @@ -0,0 +1,41 @@ +package com.example.myapplication.utils + +import android.content.Context +import android.os.Environment +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + +/** + * 基础工具类 + */ +object PathUtils { + private const val TAG: String = "BaseUtils" + const val DATE_TO_STRING_LONG_PATTERN: String = "yyyy_MM_dd_HH_mm_ss" + + fun isListEmpty(list: List?): Boolean { + return list == null || list.isEmpty() + } + + /** + * 获取应用中文件存储 + */ + fun getExternalStoragePath(context: Context): String? { + return context.getExternalFilesDir(null)?.path + } + + fun getExternalStorageDirectory(context: Context): String? { + return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).path + } + + /** + * 外部存储目录 + */ + fun getExternalStorageDirectory(): String?{ + return Environment.getExternalStorageDirectory().absolutePath + } + + fun getNowTimeFormat(dateToStringLongPattern: String): String { + return SimpleDateFormat(dateToStringLongPattern, Locale.ROOT).format(Date()); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/xls/ColumnObject.kt b/app/src/main/java/com/example/myapplication/xls/ColumnObject.kt new file mode 100644 index 0000000..c33af17 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/xls/ColumnObject.kt @@ -0,0 +1,6 @@ +package com.example.myapplication.xls + +/** + * excel到sql或者sql到excel列对象转化用 + */ +data class ColumnObject(val excelName :String, val sqTabName: String,val isImage:Boolean) \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/xls/Constants.kt b/app/src/main/java/com/example/myapplication/xls/Constants.kt new file mode 100644 index 0000000..e8fefbc --- /dev/null +++ b/app/src/main/java/com/example/myapplication/xls/Constants.kt @@ -0,0 +1,52 @@ +package com.example.myapplication.xls + +object Constants { + const val SAVE_EXPORT_EXCEL_PATH = "/WaterTransport/ExportExcel" + const val SAVE_PHOTO_PATH = "/WaterTransport/photo" + const val SAVE_AUDIO_PATH = "/WaterTransport/audio" + const val SHEET_NAME = "表格1" + const val ASSETS_PRESET_EXCEL_NAME = "preset.xls" + + const val EXCEL_EXPORT_PATH = "/WaterTransport/ExportExcel/" + lateinit var EXCEL_EXPORT_NAME: String + + //有序的 导出的excel按照这个顺序展示数据 + val COLUMN_NAME_MAP = arrayListOf( + ColumnObject("检查主题", "topicName", false), + ColumnObject("检查对象类型", "checkObj", false), + ColumnObject("检查对象", "checkerObj", false), + ColumnObject("检查人", "checker", false), + ColumnObject("检查项目", "inspectionItems", false), + ColumnObject("检查内容", "inspectionContent", false), +// ColumnObject("检查标准", "inspectionRule", false), +// ColumnObject("检查方法", "inspectionFun", false), +// ColumnObject("检查依据", "inspectionBasis", false), + ColumnObject("检查结论", "checkResult", false), + ColumnObject("检查结果备注", "checkResultRemark", false), + ColumnObject("图片", "imgPath", true), + ColumnObject("好的做法", "checkResultGood", false), + ColumnObject("好的做法备注", "checkResultRemarkGood", false), + ColumnObject("好的做法图片", "imgPathGood", true), + ) + + const val BUNDLE_KEY_TOPIC_ID = "topic_id"; + const val BUNDLE_KEY_CHECK_OBJ_DATA = "check_obj_data"; + const val BUNDLE_KEY_TITLE = "title"; + const val BUNDLE_KEY_DETAIL_CONTENT = "detail_content"; + + const val SP_NAME = "sp" + + /** + * 默认图片展示单行数量 + */ + const val DEFAULT_MEDIA_SIZE = 3 + + /** + * 默认图片展示间距 + */ + const val DEFAULT_MEDIA_OFFSET = 30 + + const val FILE_PROVIDER_AUTHORITY = ".provider" + + const val DEFAULT_VP_OFFSET = 100 +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/xls/Demo.kt b/app/src/main/java/com/example/myapplication/xls/Demo.kt new file mode 100644 index 0000000..2e7b48a --- /dev/null +++ b/app/src/main/java/com/example/myapplication/xls/Demo.kt @@ -0,0 +1,3 @@ +package com.example.myapplication.xls + +data class Demo(val content:String) diff --git a/app/src/main/java/com/example/myapplication/xls/ExcelLabelBean.kt b/app/src/main/java/com/example/myapplication/xls/ExcelLabelBean.kt new file mode 100644 index 0000000..b46a7cc --- /dev/null +++ b/app/src/main/java/com/example/myapplication/xls/ExcelLabelBean.kt @@ -0,0 +1,3 @@ +package com.example.myapplication.xls + +data class ExcelLabelBean(val excelLableContent:String, val isImage:Boolean) diff --git a/library-ijkplayer/build.gradle b/library-ijkplayer/build.gradle index 7bd1f43..2a2a344 100644 --- a/library-ijkplayer/build.gradle +++ b/library-ijkplayer/build.gradle @@ -1,24 +1,10 @@ -apply plugin: 'com.android.library' +apply from: "${rootProject.rootDir}/buildCommon/commonLibConfig.gradle" +project.ext.setLibDefaultConfig project android { - compileSdkVersion 26 lintOptions { abortOnError false } - defaultConfig { - minSdkVersion 16 - targetSdkVersion 26 - consumerProguardFiles 'proguard-rules.pro' - versionCode 38 - versionName "1.1.17.1124" - } - buildTypes { - release { - minifyEnabled true - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } - buildToolsVersion '28.0.3' } dependencies { diff --git a/library-push/build.gradle b/library-push/build.gradle index ea9f38c..ed48801 100644 --- a/library-push/build.gradle +++ b/library-push/build.gradle @@ -1,21 +1,7 @@ -apply plugin: 'com.android.library' +apply from: "${rootProject.rootDir}/buildCommon/commonLibConfig.gradle" +project.ext.setLibDefaultConfig project android { - compileSdkVersion 31 - - defaultConfig { - minSdkVersion 19 - targetSdkVersion 31 // 确保在后台预览时不崩溃。。。 - versionCode 13190817 - versionName "1.3.19.0817" - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } - }