Electron开发实战之记账软件18——备份、恢复、导入、导出

Stella981
• 阅读 542

代码仓库: https://github.com/hilanmiao/LanMiaoDesktop

备份

我们用的是json文件数据库,备份数据非常简单,直接复制文件即可。我们用fs-extra这个库操作,非常简单。

https://github.com/jprichardson/node-fs-extra

// With Promises:
fs.emptyDir('/tmp/some/dir')
.then(() => {
  console.log('success!')
})
.catch(err => {
  console.error(err)
})

// Async with promises:
fs.copy('/tmp/myfile', '/tmp/mynewfile')
  .then(() => console.log('success!'))
  .catch(err => console.error(err))

核心代码:

backup() {
                this.backuping = true
                const backupFileName = moment(new Date()).format('YYYYMMDDHHMMSS') + 'Backup.json'

                // 如果没有目录则创建
                fs.ensureDir(this.backupPath).then(() => {
                    // 复制文件
                    fs.copy(this.userDataPath + '/' + this.dbFileName, this.backupPath + '/' + backupFileName)
                        .then(() => {
                            this.backuping = false
                            this.snackbar = true
                            this.submitResult = true
                            this.snackbarMsg = 'Backup succeeded'
                        })
                        .catch(err => {
                            this.backuping = false
                            this.snackbar = true
                            this.submitResult = false
                            this.snackbarMsg = 'Backup failed'
                        })
                }).catch(err => {
                    this.backuping = false
                    this.snackbar = true
                    this.submitResult = false
                    this.snackbarMsg = 'Failed to create folder'
                })
            },

恢复

原理同备份一样,都是直接操作文件即可。恢复相当于删除和移动文件,函数使用remove和move,copy等方法。当然还有弹出文件选择框等操作。恢复完一定记得重启程序,使用relaunch、和 exist方法。

核心代码:

recovery() {
                this.recovering = true

                // 弹出文件选择框
                remote.dialog.showOpenDialog({
                    // title: '请选择需要导入的文件',
                    defaultPath: this.backupPath,
                    // buttonLabel: '确认',
                    // 过滤
                    filters: [
                        {name: 'json', extensions: ['json']}
                    ],
                    // 包含功能
                    properties: ['openFile']
                }, (filepaths, bookmarks) => {
                    if (filepaths) {
                        // 移除旧文件
                        fs.remove(this.userDataPath + '/' + this.dbFileName).then(() => {
                            // 复制文件
                            fs.copy(filepaths[0], this.userDataPath + '/' + this.dbFileName)
                                .then(() => {
                                    this.recovering = false
                                    this.snackbar = true
                                    this.submitResult = true
                                    this.snackbarMsg = 'Recovering succeeded'

                                    // 重启应用
                                    remote.app.relaunch()
                                    // remote.app.quit()
                                    remote.app.exit()
                                })
                                .catch(err => {
                                    this.recovering = false
                                    this.snackbar = true
                                    this.submitResult = false
                                    this.snackbarMsg = 'Recovering failed'
                                })
                        }).catch(err => {
                            this.recovering = false
                            this.snackbar = true
                            this.submitResult = false
                            this.snackbarMsg = 'Error deleting old files'
                        })
                    } else {
                        this.recovering = false
                    }
                })
            },

导出

导出数据是很常规的操作,我们使用exceljs这个库来做导出。

核心代码:

exportLocalFile() {
                // 日期范围判断
                if (this.search.dateStart && this.search.dateEnd) {
                    if (moment(this.search.dateStart).isAfter(moment(this.search.dateEnd))) {
                        this.snackbar = true
                        this.snackbarMsg = 'Please select the correct date range'
                        return
                    }
                }

                this.exporting = true

                // 创建一个文件
                const workbook = new Excel.Workbook()
                workbook.creator = 'test'
                workbook.lastModifiedBy = 'test'
                workbook.created = new Date()
                workbook.modified = new Date()

                // 创建一个工作组
                let sheet = workbook.addWorksheet('test')

                // 设置默认行高
                sheet.properties.defaultRowHeight = 20;

                // 创建列
                sheet.getRow(1).values = ['Detail', , 'AssetsName', 'CategoryName', 'CreatedAt', 'Remark']
                sheet.getRow(2).values = ['Type', 'AmountOfMoney', 'AssetsName', 'CategoryName', 'CreatedAt', 'Remark']

                // 设置表头样式
                const colorHeader = 'FFDB8B89'
                const rowHeader1 = sheet.getRow(2)
                rowHeader1.eachCell((cell, rowNumber) => {
                    sheet.getColumn(rowNumber).alignment = {vertical: 'middle', horizontal: 'center'}
                    sheet.getColumn(rowNumber).font = {size: 12, family: 2, bold: true}
                    sheet.getColumn(rowNumber).fill = {
                        type: 'pattern',
                        pattern: 'solid',
                        fgColor: {argb: colorHeader}
                    }
                    sheet.getColumn(rowNumber).border = {
                        top: {style: 'thin'},
                        left: {style: 'thin'},
                        bottom: {style: 'thin'},
                        right: {style: 'thin'}
                    }
                })

                // 冻结行
                sheet.views = [{
                    state: 'frozen', ySplit: 2, activeCell: 'A1'
                }]

                // 合并单元格
                sheet.mergeCells('A1:B1')
                sheet.mergeCells('C1:C2')
                sheet.mergeCells('D1:D2')
                sheet.mergeCells('E1:E2')
                sheet.mergeCells('F1:F2')

                // 添加数据项定义
                sheet.columns = [
                    {key: 'type', width: 30},
                    {key: 'amountOfMoney', width: 30},
                    {key: 'assetsName', width: 30},
                    {key: 'categoryName', width: 30},
                    {key: 'createdAt', width: 30},
                    {key: 'remark', width: 60},
                ]

                // 获取数据
                this._getModelExport().then(result => {
                    console.log(result)
                    // 创建行
                    sheet.addRows(result.data)

                    // 创建文件及文件夹
                    const APP = process.type === 'renderer' ? remote.app : app
                    // 获取electron应用的用户目录
                    const STORE_PATH = APP.getPath('userData')

                    const dir = STORE_PATH + '/export'
                    const fileName = moment(new Date()).format('YYYYMMDDHHMMSS') + 'Export.xlsx'
                    const fullPath = dir + '/' + fileName

                    // 如果没有目录则创建
                    fs.ensureDir(dir).then(() => {
                        // 写文件
                        workbook.xlsx.writeFile(fullPath).then(() => {
                            this.exporting = false

                            // 在文件管理器中显示给定的文件,如果可以,'选中'该文件
                            shell.showItemInFolder(dir)
                            // 播放哔哔的声音
                            shell.beep()

                            // 打开文件
                            shell.openItem(fullPath)
                        })
                    }).catch(err => {
                        this.snackbar = true
                        this.snackbarMsg = 'Failed to create folder'
                    })
                }).catch(err => {
                    this.snackbar = true
                    this.snackbarMsg = err.message
                })
            },

效果如下,官网还有其他的设置,可以自行参考尝试。

https://github.com/exceljs/exceljs

Electron开发实战之记账软件18——备份、恢复、导入、导出

导入

导入数据我们使用exceljsreadFile方法,它有好几个读取文件的方式,xlsx、csv、流等方式,因为我们的程序导出的xlsx文件,所以我们使用xlsx.readFile(),当然你可以可以用csv等。读取到的数据记得打印出来看看,筛选出你真正需要的数据。下面代码还用到了Electron的dialog来弹出文件选择框,但由于是renderer进程,所以要用remote.diaolog

核心代码:

importLocalFile() {
                this.importing = true

                // 弹出文件选择框
                remote.dialog.showOpenDialog({
                    // title: '请选择需要导入的文件',
                    defaultPath: this.exportPath,
                    // buttonLabel: '确认',
                    // 过滤
                    filters: [
                        {name: 'xlsx', extensions: ['xlsx']}
                    ],
                    // 包含功能
                    properties: ['openFile']
                }, (filepaths, bookmarks) => {

                    if (filepaths) {
                        // 读取文件
                        const workbook = new Excel.Workbook()
                        workbook.xlsx.readFile(filepaths[0]).then(() => {
                            // 重新结构化数据
                            let data = []

                            // 获取工作表
                            const worksheet = workbook.getWorksheet(1)
                            // 迭代工作表中具有值的所有行
                            worksheet.eachRow(function (row, rowNumber) {
                                console.log('Row ' + rowNumber + ' = ' + JSON.stringify(row.values))
                                // 去掉两行表头
                                if (rowNumber > 2) {
                                    // 重新组织数据,excel无论单元格还是行都是从1开始的
                                    const model = {
                                        type: row.values[1],
                                        amountOfMoney: row.values[2],
                                        assetsName: row.values[3],
                                        categoryName: row.values[4],
                                        createdAt: row.values[5],
                                        remark: row.values[6],
                                    }

                                    data.push(model)
                                }
                            })
                            // 业务处理
                            // console.log(data)
                            this._importData(data).then(result => {
                                if (result.code === 200) {
                                    this.submitResult = true
                                    this.importing = false
                                    this.snackbar = true
                                    this.snackbarMsg = 'Successfully imported'
                                }
                            }).catch(err => {
                                this.submitResult = false
                                this.importing = false
                                this.snackbar = true
                                this.snackbarMsg = err.message
                            })
                        })
                    }
                })
            },
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Electron开发实战之记账软件17——使用Lowdb存储数据
代码仓库:https://github.com/hilanmiao/LanMiaoDesktop(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fhilanmiao%2FLanMiaoDesktop"https://github.com/hilanmia
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Electron开发实战之记账软件20——主进程调试
代码仓库:https://github.com/hilanmiao/LanMiaoDesktop(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fhilanmiao%2FLanMiaoDesktop"https://github.com/hilanmia
Stella981 Stella981
3年前
Electron开发实战之记账软件19——通过协议唤起Electron应用
代码仓库:https://github.com/hilanmiao/LanMiaoDesktop(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fhilanmiao%2FLanMiaoDesktop"https://github.com/hilanmia
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这