Python 3.x 如何使用openpyxl和Python3在Excel文件中保存数据?有没有办法花点时间呢?

Python 3.x 如何使用openpyxl和Python3在Excel文件中保存数据?有没有办法花点时间呢?,python-3.x,excel,openpyxl,Python 3.x,Excel,Openpyxl,程序如下: 逐行读取txt文件中的数据 然后将数据发送到串行端口 将数据以数字/日期/时间的行形式保存到Excel文件中 我试过两种方法,而且都有效 但问题是: 数据越多,将新数据保存到Excel文件时花费的时间越长。例如,当将数据写入10000行时,几乎需要2秒钟(当我使用append()在Excel文件中追加新行时) 我想一直发送和保存数据,直到单击停止按钮停止Pycharm中的脚本。一旦我这样做了,以前保存的Excel已损坏,无法再次打开 我想解决这些问题。谁能给我一些建议吗?非常感谢你

程序如下:

  • 逐行读取txt文件中的数据

  • 然后将数据发送到串行端口

  • 将数据以数字/日期/时间的行形式保存到Excel文件中


  • 我试过两种方法,而且都有效

    但问题是:

  • 数据越多将新数据保存到Excel文件时花费的时间越长。例如,当将数据写入10000行时,几乎需要2秒钟(当我使用append()在Excel文件中追加新行时)

  • 我想一直发送和保存数据,直到单击停止按钮停止Pycharm中的脚本。一旦我这样做了,以前保存的Excel已损坏,无法再次打开

  • 我想解决这些问题。谁能给我一些建议吗?非常感谢你


    代码如下:

    import serial
    import serial.tools.list_ports
    import time
    import datetime
    import sys
    import os
    import openpyxl
    from openpyxl.styles import Font
    from openpyxl.styles import PatternFill
    from openpyxl.styles import Alignment
    
    
    # The path to palce the Excel file
    def creatfilepath(path):
        # path -- The user input a path
    
        if os.path.isdir(path):
            datapath = path
            print('\nM1:The path is OK, and the Excel file will be saved in {}'.format(datapath))
        else:
            if os.makedirs(path):
                datapath = path
                print('\nM2:The path does not exist, and scrip will creat the path {} to save the Excel'.format(datapath))
            else:
                datapath = os.getcwd()
                print('\nM3:Creating the path is failed, and the Excel will be saved in same path {} where the script is.'.format(datapath))
    
        return datapath
    
    
    # Creating the Excel to save the data
    def creatdatafile(filename, path, data_title):
        # filename -- Excel filename
        # path -- The path to save the Excel 
        # data_title -- Excel's title, which is a list and the default value is ['Number', 'Date', 'Time', 'Command', 'Type', 'Comment']
    
        # Creating a Workbook
        serial_data_1902_wb = openpyxl.Workbook()
    
        # Accessing the active sheet
        serial_data_1902_sheet = serial_data_1902_wb.active
    
        # sheet'title
        serial_data_1902_sheetname = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
        serial_data_1902_sheet.title = serial_data_1902_sheetname
    
        # Excel's filename
        serial_data_1902_filename = filename + '_' + \
            datetime.datetime.now().strftime('%Y%m%d_%H%M%S') + '.xlsx'
    
        # The absolute path
        ab_path = path + "\\" + serial_data_1902_filename       
    
        serial_data_1902_wb.save(ab_path)
    
        # Loading the Excel
        active_data_file = openpyxl.load_workbook(ab_path)
    
        # Accessing the sheet
        active_datasheet = active_data_file[serial_data_1902_sheetname]
    
        # Setting the title
        row_title = data_title
        active_datasheet.append(row_title)
    
        # Freezing the 1st row
        active_datasheet.freeze_panes = 'A2'
    
        # Accessing the title's scope
        title_scope = active_datasheet.dimensions
    
        # Arial/12/Bold/
        title_font_obj = Font(name='Arial', size=10, bold=True,
                              italic=False, strike=False, color='000000')
    
        # Fill type
        title_fill_obj = PatternFill(fill_type='solid', fgColor='7EC0EE')
    
        # Alignment
        title_align_obj = Alignment(
            horizontal='center', vertical='center', wrap_text=False)
    
        # Formating the 1st row
        for rowOfCellObjects in active_datasheet[title_scope]:
            for cellObject in rowOfCellObjects:        
                cellObject.font = title_font_obj
                cellObject.fill = title_fill_obj
                cellObject.alignment = title_align_obj
    
        active_data_file.save(ab_path)
    
        # Return the absolute path
        if os.path.exists(ab_path):
            print('\nM4:The Excel {} have created, and the path is {}'.format(
                serial_data_1902_filename, path))
            return ab_path
        else:
            print('\nE0:Creating Excel is failed, please check!')
            sys.exit(0)
    
    
    def isavailable(port):
    
        port_list = list(serial.tools.list_ports.comports()
                         )        
    
        if len(port_list) <= 0:
            print('\nE1:There is not serial port on the host!')
            sys.exit(0)
        else:
            port_name_list = []
    
            for port_objet in port_list:
                port_name = port_objet[0]
    
                port_name_list.append(port_name.lower())
    
            print('\nM5:The serial ports is:{}'.format(port_name_list))
    
        if port.lower() in port_name_list:       
            print('\nM6:')
        else:
            print('\nE2:')
            sys.exit(0)
    
    
    # Creating a vitural serial port and open it
    def createport(port, baudrate=115200):
    
        isavailable(port)
    
        try:
            serialport = serial.Serial(port, baudrate, timeout=1, write_timeout=1)
        except ValueError:
            sys.exit('\nE3:')
        except (OSError, serial.SerialException):
            sys.exit('\nE4:')
    
        if serialport.is_open and port == serialport.portstr:       
            print('\nM7:')
            serialport.flushInput()        
        else:
            sys.exit('\nE5:')
    
        return serialport
    
    
    def savecommand(num, command_list, excelabpath, excelworkbook, excelsheet):
        # num --  The number of command
        # command_list -- A list which contain the data
        # excelabpath -- The absolute path of Excel
        # excelworkbook -- The Excel which save data
        # excelsheet -- the sheet which save the data
    
        try:
            i = 0
            for row in excelsheet.iter_rows(min_row=num+1, max_col=5, max_row=num+1):
                for cell in row:
                    cell.value = command_list[i]
                    i += 1
    
                    if i < len(command_list):
                        continue
                    else:
                        break
    
            excelworkbook.save(excelabpath)
        except TypeError:
            print('\nE10:')
    
    
    def sendcommand(abpath, workbook, sheet, commandfile, port, intertime=0.5, commamd_num=1):
        #
        if not port.is_open:
            try:
                port.open()
            except:
                print('\nE6:')
        else:
            pass
    
    
        try:
            with open(commandfile, 'r', encoding='utf-8') as file_object:
                for line in file_object:
                    if len(line) > 1 and (not line.startswith('#')):
                        command_hex = bytes.fromhex(
                            line.strip())
                        try:
                            print(commamd_num, " ", datetime.datetime.now(),
                                  " ", line)
    
                            port.write(command_hex)
    
                            # The list contain the number/date/time/command
                            data_list = [commamd_num, datetime.datetime.now().strftime(
                                '%Y/%m/%d'), datetime.datetime.now().strftime('%H:%M:%S.%f'), line.strip()]
    
                            savecommand(commamd_num, data_list, abpath, workbook, sheet)
    
                            time.sleep(intertime)
    
                            commamd_num += 1
    
                        except serial.SerialTimeoutException:
                            print("\nE7:")
    
                            time.sleep(1)
                            port.write(command_hex)
    
                            # The list contain the number/date/time/command
                            data_list = [commamd_num, datetime.datetime.now().strftime(
                                '%Y/%m/%d'), datetime.datetime.now().strftime('%H:%M:%S.%f'), line.strip()]
    
                            savecommand (commamd_num, data_list, abpath, workbook, sheet)
    
                            time.sleep(intertime)
    
                            commamd_num += 1
                    else:
                        continue
        except FileNotFoundError:
            print('\nE8:')
            sys.exit(0)
        except PermissionError:
            print('\nE9:')
            sys.exit(0)
    
        port.close()
    
        if not port.is_open:
            print('\nM9:')
    
        return commamd_num 
    
    
    # ~~~~~~~~~~~~~~ The parameters of serial port ~~~~~~~~~~~~~~~~~~
    # port number
    comNumber = 2
    # port name
    comPort = 'com{}'.format(comNumber)
    # baudRate
    baudRate = 115200
    
    # ~~~~~~~~~~~~~~ Other parameters ~~~~~~~~~~~~~~~~~~
    # The path of command file
    commandPath = r'.\1902.txt'
    
    # The Excel path
    savePath = r'D:\1902Code'
    
    # The name of Excel
    excelName = 'SerialData1902'
    
    # The title
    excelTitle = ['Number', 'Date', 'Time', 'Command', 'Type', 'Comment']
    
    # The time between two command was sent
    interTime = 0.01
    
    # 
    isForever = 1
    
    
    # ~~~~~~~~~~~~~~~~~~~~~  Begin ~~~~~~~~~~~~~~~~~~~
    
    # Creating the path which save the Excel
    excel_path = creatfilepath(savePath)
    
    # Creating the Excel
    excel_ab_path = creatdatafile(excelName, excel_path, excelTitle)
    
    # Loading the Excel
    excel_workbook = openpyxl.load_workbook(excel_ab_path)
    
    # Accessing the sheet
    excel_sheet = excel_workbook.active
    
    # Creating the serial port
    serial_port = createport(comPort, baudRate)
    
    # The number of sending command and start with 1
    command_num = 1
    
    
    if isForever:
        print('\nM10:')
        while isForever:
            command_num = sendcommand(excel_ab_path, excel_workbook, excel_sheet,
                                      commandPath, serial_port, interTime, command_num)
    elif isForever == 0:
        print('\nM11:')
        command_num = sendcommand(excel_ab_path, excel_workbook, excel_sheet,
                                  commandPath, serial_port, interTime, command_num)
    else:
        print('\nE11:')
    
    
    导入序列号
    导入serial.tools.list_端口
    导入时间
    导入日期时间
    导入系统
    导入操作系统
    导入openpyxl
    从openpyxl.styles导入字体
    从openpyxl.styles导入填充图案
    从openpyxl.styles导入对齐方式
    #保存Excel文件的路径
    def creatfilepath(路径):
    #path——用户输入一个路径
    如果os.path.isdir(路径):
    数据路径=路径
    打印('\nM1:路径正常,Excel文件将以{}格式保存(数据路径))
    其他:
    如果os.makedirs(路径):
    数据路径=路径
    打印('\nM2:路径不存在,scrip将创建路径{}以保存Excel'.format(datapath))
    其他:
    datapath=os.getcwd()
    打印('\nM3:创建路径失败,Excel将保存在脚本所在的相同路径{}。格式(数据路径))
    返回数据路径
    #创建Excel以保存数据
    def creatdatafile(文件名、路径、数据标题):
    #文件名--Excel文件名
    #path——保存Excel的路径
    #data_title——Excel的标题,是一个列表,默认值为['Number'、'Date'、'Time'、'Command'、'Type'、'Comment']
    #创建工作簿
    serial_data_1902_wb=openpyxl.Workbook()
    #访问活动工作表
    串行数据表=串行数据表
    #书名
    serial\u data\u 1902\u sheetname=datetime.datetime.now().strftime(“%Y%m%d\u%H%m%S”)
    serial_data_1902_sheet.title=serial_data_1902_sheet name
    #Excel的文件名
    串行_数据_1902_文件名=文件名+''+\
    datetime.datetime.now().strftime(“%Y%m%d_%H%m%S”)+”.xlsx'
    #绝对路径
    ab\U path=path+“\\”+串行数据\U 1902\U文件名
    串行数据保存(ab路径)
    #加载Excel
    活动\u数据\u文件=openpyxl.load\u工作簿(ab\u路径)
    #访问工作表
    活动数据表=活动数据文件[串行数据表名称]
    #设置标题
    行标题=数据标题
    活动数据表。附加(行标题)
    #冻结第一排
    活动\数据表.冻结\窗格='A2'
    #访问标题的范围
    title\u scope=活动的\u数据表.dimensions
    #Arial/12/Bold/
    title\u font\u obj=font(name='Arial',size=10,bold=True,
    斜体=假,删除=假,颜色='000000')
    #填充类型
    title\u fill\u obj=PatternFill(fill\u type='solid',fgColor='7EC0EE')
    #对齐
    标题\对齐\对象=对齐(
    水平class='center',垂直class='center',换行(文本=False)
    #形成第一行
    对于活动\u数据表[标题\u范围]中的rowOfCellObjects:
    对于第行CellObjects中的cellObject:
    cellObject.font=标题\u字体\u对象
    cellObject.fill=标题\u fill\u对象
    cellObject.alignment=标题\对齐\对象
    活动数据文件。保存(ab路径)
    #返回绝对路径
    如果os.path.存在(ab_路径):
    打印('\nM4:Excel{}已创建,路径为{}'。格式(
    串行_数据_1902_文件名,路径))
    返回ab_路径
    其他:
    打印('\nE0:创建Excel失败,请检查!')
    系统出口(0)
    def可用(端口):
    port\u list=list(serial.tools.list\u ports.comports()
    )        
    如果len(port_list)1和(而不是line.startswith(“#”):
    命令\u hex=bytes.fromhex(
    line.strip())
    尝试:
    打印(commamd_num,“,datetime.datetime.now(),
    “”,第行)
    端口写入(命令\十六进制)
    #该列表包含编号/日期/时间/命令
    data_list=[commamd_num,datetime.datetime.now().strftime(
    “%Y/%m/%d”),datetime.datetime.now().strftime(“%H:%m:%S.%f”),line.strip()]
    savecommand(commamd\u num、数据列表、abpath、工作簿、工作表)
    时间。睡眠(时间间隔)
    commamd_num+=1
    除serial.SerialTimeoutException外:
    打印(“\nE7:”)
    时间。睡眠(1)
    端口写入(命令\十六进制)
    #该列表包含编号/日期/时间/命令
    data_list=[commamd_num,datetime.datetime.now().strftime(
    “%Y/%m/%d”),datetime.datetime.now().strftime(“%H:%m:%S.%f”),line.strip()]
    savecommand(commamd\u num、数据列表、abpath、工作簿、工作表)
    时间。睡眠(时间间隔)
    commamd_num+=1
    其他:
    持续
    除FileNotFoundError外:
    打印('\nE8:')
    系统出口(0)
    除许可错误外:
    打印('\nE9:')
    系统出口(0)
    端口关闭()
    如果端口未打开:
    打印('\nM9:')
    返回commamd_num
    #~~~~~~~~~~~~~~~~~~~的参数