之前有遇到一个需求:在不使用后端服务的情况下,支持在移动端动态查看某公司OA部门员工状态数据。
整个前端H5项目基于uni-app开发,使用的框架是Vue
实现思路
- 是否可以把数据通过某种形式保存到手机本地缓存中
- 是否能够在打开某app或者小程序能直接获取到手机本地缓存的数据来渲染页面
- 全程后端不参与,那么前端能否访问手机内部文件,并且自动解析文件内容并生成json数据
- 拿到json数据后,可以通过什么样的方式存到手机本地存储中,并且可以支持条件查询筛选功能
SQLite
SQLite模块用于操作本地数据库文件,可实现数据库文件的创建,执行SQL语句等功能。
具体API参考官方文档
// 判断数据库是否打开
plus.sqlite.isOpenDatabase({
name: dbName,
path: dbPath
})
// 打开数据库
plus.sqlite.openDatabase({
name: dbName,
path: dbPath,
success:fn
fail:fn
})
// 关闭数据库
plus.sqlite.closeDatabase({
name: dbName,
path: dbPath,
success:fn
fail:fn
})
// 表格的相关操作
// 根据sql的不同可以实现表格的创建、删除、插入等
plus.sqlite.selectSql({
name: dbName,
sql: sql,
success:fn
fail:fn
})
复制代码
uni-app使用SQLite
1.选中SQLite
2.自定义调试基座
参考链接uniapp 安卓手机真机模拟
3.根据SQlite文档实现相关操作
打开数据库、关闭数据库、创建表、删除表、查询数据、新增数据、删除数据等
复制代码
需求实现
uniapp端实现选择手机内部文档,通过前端解析文档内容生成json数据
获取json后,使用sqlite对本地缓存下数据进行处理
查询相关数据进行页面渲染
选择并获取文件
1)H5端
普通的PC端web或者H5,有dom操作对象,可以通过传统的input标签的点击和change
事件实现
2)App端
非H5的uni-app是没有dom对象的,一般会直接在插件商城中下载安装常用的文件选择获取插件,来获取文件的path
根据获取的文件路径或者文件对象获取文件内容
1)H5端
HTML
<input type="file" id="myfile" name="myfile" style="display:none" />
<button id="uploader" style="width: 200px; height: 50px;" onclick="document.getElementById('myfile').click()">上传</button>
复制代码
JS
// 监听input的change事件,最终获取当前选择的文件对象
document.getElementById('myfile').onchange = (event) => {
var selectedFile = event.target.files[0];
console.log(selectedFile)
// 新建FileReader对象
var reader = new FileReader();
reader.onload = function(event) {
// 获取当前文件内容
var data = event.target.result;
}
// 读取上传文件为二进制
reader.readAsBinaryString(selectedFile);
}
复制代码
2)App端
首页通过导入的插件选择获取到当前文件的路径,
根据plus.io
获取具体文件对象 plus.io.FileReader,
fileReader.readAsDataURL
,
fileReader.readAsText
fileReader:function(){
const self = this;
// 请求本地系统文件对象 plus.io.PRIVATE_WWW:应用运行资源目录常量
plus.io.requestFileSystem( plus.io.PRIVATE_DOC, function(fobject){
// fs.root是根目录操作对象DirectoryEntry
fobject.root.getFile('config.xml',{create:true},function(fileEntry){
fileEntry.file( function(file){
var fileReader = new plus.io.FileReader();
fileReader.readAsText(file, 'utf-8');
fileReader.onloadend = function(evt) {
//evt 里面包含有当前文件的具体内容,但是不同文件类型的编码格式不确定,目前api中只有txt和img
}
});
});
});
},
复制代码
解析文件内容,生成JSON字符串
plus.io
上述有说到,在app端,通过
plus.io
获取文件内容,目前只支持两种编码格式
fileReader.readAsDataURL
以URL编码格式读取文件数据内容,适用于图片类型
fileReader.readAsText
以文本格式读取文件数据内容,适用于txt文本类型
excel类型的文件应该怎么做?
之前考虑说是否可以根据上面的两个api来获取并手动转码的形式来获取具体的内容生成json,但是在编码格式上一直是有问题的,所以目前来说,对于excel文件还没有找到app端的实现方式(遗留问题 有知道的小伙伴?我
)
那么我们是不是可以通过在app端嵌入H5的方式实现?
web-view
采用web-view标签,嵌入H5页面
<web-view src="/hybrid/html/index.html" @message="handleMessage"></web-view>
复制代码
注意:
1. h5页面必须在项目目录:hybrid/html/
下面,因为这样uni-app才不会进行编译
2. uniapp跳转webview后H5会执行UniAppJSBridgeReady
回调
// 跳转后
document.addEventListener('UniAppJSBridgeReady', function() {
// 具体实现文件选择、获取、内容格式转换、向uni-app传值代码都卸载这个回调里
})
复制代码
3. H5页面向uni-app传值
uni.postMessage({
data: XL_row_object
});
复制代码
4. @message
事件是h5页面向应用发送数据的回调
// uniapp获取webview传来的值
handleMessage(evt) {
this.dataInfo = evt.detail.data
}
复制代码
XLSX
excel格式化
var workbook = XLSX.read(data, {
type: 'binary'
});
console.log(event.target.result)
workbook.SheetNames.forEach(function(sheetName) {
var XL_row_object = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
if (XL_row_object.length > 0) { console.log(JSON.stringify(XL_row_object));
//向uniapp传值
uni.postMessage({
data: XL_row_object
});
}
})
复制代码
通过SQlite语法操作JSON
前端将获取到的JSON内容通过SQlite存入到本地存储中,关闭数据库连接后,本地存储的内容依然存在
访问数据库连接,查询对应的数据信息并渲染到APP页面上
完整代码
H5
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<title>附件上传</title>
</head>
<body>
<h1>附件上传</h1>
<input type="file" id="myfile" name="myfile" style="display:none" />
<button id="uploader" style="width: 200px; height: 50px;" onclick="document.getElementById('myfile').click()">上传</button>
<!-- uni 的 SDK -->
<script type="text/javascript" src="js/uni.webview.1.5.2.js"></script>
<script type="text/javascript" src="js/xlsx.mini.js"></script>
<script type="text/javascript">
// 跳转后
document.addEventListener('UniAppJSBridgeReady', function() {
document.getElementById('myfile').onchange = (event) => {
var selectedFile = event.target.files[0];
console.log(selectedFile)
var reader = new FileReader();
reader.onload = function(event) {
var data = event.target.result;
console.log(typeof event.target.result)
var workbook = XLSX.read(data, {
type: 'binary'
});
workbook.SheetNames.forEach(function(sheetName) {
var XL_row_object = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
if (XL_row_object.length > 0) {
//向uniapp传值
uni.postMessage({
data: XL_row_object
});
}
})
};
reader.onerror = function(event) {
console.error("File could not be read! Code " + event.target.error.code);
};
// 读取上传文件为二进制
reader.readAsBinaryString(selectedFile);
}
});
</script>
</body>
</html>
复制代码
uni-app
fileUpload.vue
<template>
<view>
<template v-if="show">
<web-view src="/hybrid/html/index.html" @message="handleMessage"></web-view>
</template>
<view>
{{lastInfo}}
</view>
</view>
</template>
<script>
export default {
data() {
return {
dataInfo:'',
show:true,
}
},
computed:{
lastInfo() {
return this.dataInfo
}
},
methods: {
handleMessage(evt) {
this.dataInfo = evt.detail.data
this.show = false
}
},
}
</script>
复制代码