搜 索

随手记如何免费高效迁移到一木记账|随手记账单免费导出|随手记kdf文件打开解析

  • 29阅读
  • 2024年05月16日
  • 0评论
首页 / ✒舞文弄墨 / 正文

背景

随手记是金蝶出品的一款记账软件,其实还是不错的,不过我从来没有充过会员,一直也长期用着用了有快三年了,已经有快4000条流水了,每天坚持记账也养成了挺好的习惯。不过近期正好在尝试其他的记账APP,所以发现了竟然还有语音记账和自动记账等功能(自动记账利用的是安卓的无障碍功能识别界面内容来触发),试用了一下还挺好用的。因此我就计划迁移出随手记了,迁移到我试用了还不错的一木记账App来使用。

但是在迁移的过程中却发现随手记APP的Excel导出是需要会员的,我就导出一下就不用你了竟然收我14块钱一个月的费用,实在太不划算了。

账本的设置-高级功能-备份与同步-导出数据到Excel(CSV)竟然是锁住的,免费版用户导出不了,得充值14块钱一个月才行。

微信图片_20240516204928.jpg

于是到处找解决的方案,最后发现,在设置-高级功能-备份与同步-本地备份与恢复,可以进行免费的导出。导出的文件是kdf后缀的文件,不是常见的文件类型,只有随手记app自己可以导入和解析恢复,那么我们要怎么取到里面的账单内容呢?

一顿好找,最后在吾爱破解找到一个大佬的kdf的解析的文章,其实kdf的本质是一个zip的压缩包里面呢包含了一个sqlite数据库,还有一些其他文件,这个sqlite数据库就是我们需要的账单了。但这个sqlite数据库的文件头是被魔改的,需要改回来才能用。

不过可惜,这位吾爱大佬的文章中给的代码是他自己用的,缺少了非常多的关键信息,因此直接执行是无法执行的,同时我要导入一木记账的代码是并没有的,因此努力修改了一下原始的代码思路,目前已经可以直接使用啦!

将随手记kdf解密并生成可阅读的sqlite数据库

首先我们需要从随手记里面“免费”导出kdf账单文件。

在设置-高级功能-备份与同步-本地备份与恢复中导出即可,然后把该文件传输到电脑的某个上,并修改文件名为record.kdf方便我们后续的处理。

image-20240516211021416.png

接下来,运行我们的第一个脚本:

import zipfile
import os
def unzip_kbf(input_files=None):
    zf = zipfile.ZipFile(input_files)
    zf.extractall(path='./')

def ssj_kbf_sqlite_convert(input_file, output_file):
    """
    convert ssj data, after kbf unzip to sqlite,convert it to normal sqlite database file
    :param input_file: the mymoney.sqlite file path
    :param output_file: the convert mymoney.sqlite file path
    :return:
    """
    sqlite_header = (0x53, 0x51, 0x4C, 0x69,
                     0x74, 0x65, 0x20, 0x66,
                     0x6F, 0x72, 0x6D, 0x61,
                     0x74, 0x20, 0x33, 0x0)
    if os.path.exists(output_file):
        os.remove(output_file)
    with open(input_file, mode='rb') as f:
        with open(output_file, mode='wb') as fw:
            data_buffer = f.read()
            write_buffer = bytearray(data_buffer)
            index = 0
            while index < len(sqlite_header):
                write_buffer[index] = sqlite_header[index]
                index = index + 1
            fw.write(write_buffer)
    print("convert done")

# 执行kbf文件解密
unzip_kbf("record.kbf")
ssj_kbf_sqlite_convert("mymoney.sqlite", "record_decrypt.sqlite")

此时该文件夹即可生成一个已经解密的record_decrypt.sqlite文件。

这个文件就是可以直接读取数据的数据了,我们使用一些数据库读取的工具就可以查看里面的内容了,比如navicat等等。其中的t_transaction表就是我们交易的账单了。

当然还有其他的一些表还需要进行联立,我们只需要使用sql的知识把我们需要的字段弄出来即可。

生成导入到一木记账的Excel模板

首先一木记账的模板可以在一木记账APP里面导出来,大概长这样:

image-20240516211736700.png

于是我也给你提供了我测试好可以导入的获取的代码,使用代码之前你需要安装一下三方的库:

pip install pandas xlwt

接下来是代码:

import sqlite3
import pandas as pd
import xlwt

# 连接到SQLite数据库,如果数据库文件不存在,会自动在当前目录创建一个
# 数据库文件名为example.db
conn = sqlite3.connect('record_decrypt.sqlite')

# 创建一个游标对象,用于执行SQL语句
cursor = conn.cursor()

sql = '''SELECT strftime('%Y-%m-%d %H:%M', a.tradeTime / 1000 + 8 * 3600, 'unixepoch') as 日期,
 case
   when a.type = 1 then '收入'
     when a.type = 0 then '支出'
 end as 收支类型,
 case
   when a.type = 1 then (select case 
                             when (select b.currencyType from t_account b where b.accountPOID = a.sellerAccountPOID) = 'CNY' then a.buyerMoney
                                                     else (select round(a.buyerMoney * d.rate, 2) from 
                                                                    (select b.currencyType from t_account b where b.accountPOID = a.sellerAccountPOID) c, 
                                                                    t_exchange d where c.currencyType = d.sell)
                                                     end)
   when a.type = 0 then (select case 
                             when (select b.currencyType from t_account b where b.accountPOID = a.buyerAccountPOID) = 'CNY' then a.buyerMoney
                                                     else (select round(a.buyerMoney * d.rate, 2) from 
                                                                    (select b.currencyType from t_account b where b.accountPOID = a.buyerAccountPOID) c, 
                                                                    t_exchange d where c.currencyType = d.sell)
                                                     end)
 end as 金额,
 case 
   when a.type = 1 then (select d.name from (select b.parentCategoryPOID from t_category b 
                              where b.categoryPOID = a.buyerCategoryPOID) c, t_category d
                                                            where c.parentCategoryPOID = d.categoryPOID)
     when a.type = 0 then (select d.name from (select b.parentCategoryPOID from t_category b 
                              where b.categoryPOID = a.sellerCategoryPOID) c, t_category d
                                                            where c.parentCategoryPOID = d.categoryPOID)
 end as 类别,
 case 
   when a.type = 1 then (select b.name from t_category b where b.categoryPOID = a.buyerCategoryPOID)
     when a.type = 0 then (select b.name from t_category b where b.categoryPOID = a.sellerCategoryPOID)
 end as 子类,
 '日常账本' as 所属账本,
 case 
   when a.type = 1 then (select b.name from t_account b where b.accountPOID = a.sellerAccountPOID)
     when a.type = 0 then (select b.name from t_account b where b.accountPOID = a.buyerAccountPOID)
 end as 收支账户,
 a.memo as 备注,
 (select c.name 
     from t_transaction_projectcategory_map b, t_tag c 
     where b.transactionPOID = a.transactionPOID 
     and b.projectCategoryPOID = c.tagPOID
     and b.type = 2) as 标签,
 '' as 地址
 FROM t_transaction a
 order by a.tradetime desc;'''

# 运行一个查询语句
select_sql = sql

# 使用游标执行查询
cursor.execute(select_sql)

# 获取所有查询结果
results = cursor.fetchall()

# 打印结果
for row in results:
    print(row)

# 将结果转换为DataFrame
columns = [column[0] for column in cursor.description]  # 获取列名
df = pd.DataFrame(results, columns=columns)

# 关闭游标和连接
cursor.close()
conn.close()

# 使用xlwt库将DataFrame写入Excel文件
excel_filename = '一木记账导入.xls'

# 创建一个Excel工作簿
wb = xlwt.Workbook()
# 添加一个工作表
ws = wb.add_sheet('Sheet 1')

# 将DataFrame数据写入Excel工作表
for col_num, col_data in enumerate(df.columns):
    ws.write(0, col_num, col_data)  # 写入列名

for row_num, row_data in enumerate(df.values):
    for col_num, col_data in enumerate(row_data):
        ws.write(row_num + 1, col_num, col_data)  # 写入单元格数据

# 保存Excel文件
wb.save(excel_filename)

print(f'数据已成功写入到 {excel_filename}')

完成后生成的文件效果如下:

image-20240516212101797.png

接下来就很简单了,使用导出好的这个xls文件,在一木记账中打开或者点导入即可成功导入啦!

希望能对大家有所帮助,谢谢!

评论区
暂无评论
avatar