DBC转excel(python语言)

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

    重复造轮子只是为了熟悉一下DBC格式。
    与同类工具的不同点

    1. 能批量转换在同一文件夹下的所有DBC省时省力。
    2. 很多同类工具转换后的excel列宽较小不能直接显示全部信息。本代码使用了自适应的列宽看起来更方便。**
    # coding=UTF-8
    import os
    import argparse
    import xlsxwriter as xw
    import pandas as pd
    import re
    import openpyxl
    
    
    # DBC信息解码返回字典
    def decode(str1):
        ans = {}
        # 报文帧
        if str1.startswith('BO_'):
            list1 = re.split(" |: |\n",str1)
            ans['message_id'],ans['message_name'],ans['message_size'],ans['transmitter'] = list1[1],list1[2],list1[3],list1[4]
            return ans
        # 信号帧
        elif str1.startswith(' SG_'):
            str1 = str1[5:] # 去掉" SG_ ",共5个字符
            ans['empty1'],ans['empty2'],ans['empty3'],ans['empty4'] = None,None,None,None
    
            sub = ':'
            spt = [sub.start() for sub in re.finditer(sub , str1)]
            ans['signal_name'],ans['multiplexer_indicator'] = re.split(" ",str1[0:spt[0]])[0], re.split(" ",str1[0:spt[0]])[1]
            str1 = str1[spt[0]+2:]
    
            sub = '@'
            spt = [sub.start() for sub in re.finditer(sub , str1)]
            ans['start_bit'],ans['signal_size'],ans['byte_order'],ans['value_type'] = str1[0: str1.find('|',0,spt[0])], str1[str1.find('|',0,spt[0])+1:spt[0]], str1[spt[0]+1], str1[spt[0]+2]
            if ans['byte_order'] == '0':
                ans['byte_order'] = 'intel'
            elif ans['byte_order'] == '1':
                ans['byte_order'] = 'motorola'
            if ans['value_type'] == '+':
                ans['value_type'] = '无符号数'
            elif ans['value_type'] == '-':
                ans['value_type'] = '有符号数'
            str1 = str1[spt[0]+4:]
    
            spt = str1.find(' ')
            ans['factor'],ans['offset'] = re.split(",",str1[1:spt-1])[0], re.split(",",str1[1:spt-1])[1]
            str1 = str1[spt+1:]
    
            sub = ']'
            spt = [sub.start() for sub in re.finditer(sub , str1)]
            ans['minimum'],ans['maximum'] = str1[1: str1.find('|',0,spt[0])], str1[str1.find('|',0,spt[0])+1:str1.find(']')]
            str1 = str1[spt[0]+2:]
            ans['unit'],ans['receiver'] = str1[0:str1.find(' ')], str1[str1.find(' ')+1:-2]
    
            return ans
        
        
    if __name__ == '__main__':
    
        parser = argparse.ArgumentParser(description='将文件夹中的所有DBC文件转换为excel')
        parser.add_argument('dbc_dir', type=str,help='DBC文件所在的文件夹地址')
        parser.add_argument('excel_dir', type=str,help='excel的保存地址')
        parser.add_argument('excel_name', type=str,help='excel文件名')
        args = parser.parse_args()
        dbc_dir = args.dbc_dir
        excel_dir = args.excel_dir
        excel_name = args.excel_name
    
        title = ['message_id', 'message_name', 'message_size','transmitter', 'signal_name', 'multiplexer_indicator',
            'start_bit', 'signal_size', 'byte_order', 'value_type','factor', 'offset', 'minimum', 'maximum', 'unit', 'receiver']
        
        # 遍历指定文件夹下的DBC文件绝对路径保存为list。
        dbcfiles = []
        for filename in os.listdir(dbc_dir):
            if filename.endswith('.dbc'):
                dbcfiles.append(filename)
    
        df = pd.DataFrame()
        df.to_excel(excel_name)
    
        for dbc in dbcfiles:
            # 将数据按表头顺序存入list
            with open(dbc_dir + '/' + dbc, 'r', encoding='gbk') as f:
                string = f.readlines()
            for i in string:
                data = decode(i)
                # data = translate(data)
                if data != None:
                    val = list(data.values())
                    df1 = pd.DataFrame([val])
                    df = pd.concat([df,df1],axis=0)
        
            with pd.ExcelWriter(excel_name, mode='a', engine="openpyxl") as writer:
                df.to_excel(writer, sheet_name=dbc, header=title, index=False)
    
        workbook = openpyxl.load_workbook(excel_name)
        worksheet = workbook['Sheet1']
        workbook.remove(worksheet)
        for sheet_name in workbook.sheetnames:
            sheet = workbook[sheet_name]
            for column in sheet.columns:
                max_length = 0
                column = [cell for cell in column]
                for cell in column:
                    try:
                        if len(str(cell.value)) > max_length:
                            max_length = len(cell.value)
                    except:
                        pass
                adjusted_width = (max_length + 2)
                sheet.column_dimensions[column[0].column_letter].width = adjusted_width
        workbook.save('dbctoexcel.xlsx')
    
    
    
    
    
    
    
    
  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
    标签: python