Python腳本之讀寫Excel【三】

手上的某些需求 用到xlsx格式的Excel的生成、解析,之前分享過: Excel大數據量的讀寫Excel的讀寫,這兒說下,關於日期格式的處理。

需求

假設要用的Excel 有些字段是日期,有固定的某格式,要如何來寫入? 如何來讀取呢?

下圖是我用腳本模擬生成的Excel。可以看到有2個字段【Transaction time、Settlement time】,和日期有關係。
在這裏插入圖片描述

若只是某1個文件,最簡單的方法是 在Excel中打開“單元格格式”對話框,在【數字】設置所需的格式:

在這裏插入圖片描述
在這裏插入圖片描述
但需求既然要和Excel有關,那就不可能只一個Excel,所以還得用代碼來實現。

寫入

The Format Class 這是xlsxwriter官方網站

在這裏插入圖片描述
再結合我之前 在第一篇分享 Excel大數據量的讀寫 說的寫入方法,優化代碼後,就是 :

        date_format = workbook.add_format({'num_format': 'yyyy-mm-dd hh:mm:ss'})
        sheet.write_row(row=i - 1, col=5, data=[datetime.datetime.strptime(t_time, '%Y%m%d %H:%M:%S')], cell_format=date_format)
        
        date_format_1 = workbook.add_format({'num_format': 'm/d/yy h:mm AM/PM'})
        sheet.write_row(row=i - 1, col=6,
                        data=[datetime.datetime.strptime(s_time, '%Y%m%d %H:%M:%S') if s_time is not None else s_time],
                        cell_format=date_format_1)

有些想說的: 1. data字段值 應當是一個 datetime.datetime, datetime.date datetime.time 或datetime.timedelta對象 ;2. data 字段值格式有要求: A list of tokens to be written with write()

單sheet和多sheet的處理

除了對日期格式的注意,還會考慮單sheet和多sheet的情況。 我在第一篇分享 Excel大數據量的讀寫,默認使用的多sheet,這兒優化了一下。

    def insert_excel(self, all_data, header):
        """
        數據 寫入Excel
        :param all_data:
        :param header:
        :return:
        """

        cr_time = time.strftime("%Y%m%d_%H%M%S")
        w = r'D:\work\test_' + cr_time + '.xlsx'

        workbook = xlsxwriter.Workbook(w, {'constant_memory': True})
        if isinstance(all_data[0], tuple) is True:
            all_data.insert(0, tuple(header))
            self.insert_data_to_excel(workbook, '0', all_data)
        else:

            for abc in range(len(all_data)):
                all_data[abc].insert(0, header)
                self.insert_data_to_excel(workbook, str(abc), all_data[abc])

        workbook.close()

    def insert_data_to_excel(self, workbook, sheet_name, sheet_data):
        """
        實際 寫入
        :param workbook:
        :param sheet_name:
        :param sheet_data:
        :return:
        """

        sheet = workbook.add_worksheet(sheet_name)
        date_format = workbook.add_format({'num_format': 'yyyy-mm-dd hh:mm:ss'})
        date_format_1 = workbook.add_format({'num_format': 'm/d/yy h:mm AM/PM'})

        Log.info('sheet{} 準備新建'.format(sheet_name))

        for i in range(1, len(sheet_data) + 1):
            t_time = sheet_data[i - 1][5]
            s_time = sheet_data[i - 1][6]

            if t_time.find('time') != -1 and s_time.find('time') != -1:
                Log.info('第一行 表頭')
                sheet.write_row(row=i-1, col=0, data=sheet_data[i - 1])

            else:
                sheet.write_row(row=i-1, col=0, data=sheet_data[i - 1][0:5])

                sheet.write_row(row=i-1, col=5, data=[datetime.datetime.strptime(t_time, '%Y%m%d %H:%M:%S') if t_time is not None else t_time], cell_format=date_format)

                sheet.write_row(row=i-1, col=6, data=[datetime.datetime.strptime(s_time, '%Y%m%d %H:%M:%S') if s_time is not None else s_time], cell_format=date_format_1)

                sheet.write_row(row=i-1, col=7, data=sheet_data[i - 1][7:])

        Log.info('當前sheet已生成')

讀取

使用xlrd讀取時間字段 讀取出來是浮點數,在使用時需要轉換成對應的datetime類型,可以用 xldate_as_tuple()

    def read_excel(self):
        import xlrd
        from xlrd import xldate_as_tuple

        # 故意寫死
        name = 'test_20200612_172106.xlsx'
        file = ''.join(['D:\work\\aku\\', name])

        book = xlrd.open_workbook(file)
        all_sheets = book.sheets()
        all_data = list()

        for s in all_sheets:
            sheet = book.sheet_by_name(s.name)
            hang = range(0, sheet.nrows)

            for c in hang:
                ele = sheet.row_values(c)
                Log.info(ele)
                if isinstance(ele[5], str) is False:        # Transaction time讀取的字段值 非str
                    tu_5 = xldate_as_tuple(ele[5], 0)
                    Log.info(tu_5)
                    str_5 = datetime.datetime(tu_5[0], tu_5[1], tu_5[2], tu_5[3], tu_5[4], tu_5[5]).strftime("%Y%m%d %H:%M:%S")
                    if ele[6] != '':
                        tu_6 = xldate_as_tuple(ele[6], 0)
                        Log.info(tu_6)
                        ele_6 = datetime.datetime(tu_6[0], tu_6[1], tu_6[2], tu_6[3], tu_6[4], tu_6[5]).strftime("%Y%m%d %H:%M:%S")
                    else:
                        ele_6 = None

                    all_data.append(tuple(ele[0:5]) + (str_5, ele_6) + tuple(ele[7:]))
                else:
                    all_data.append(ele)

        Log.info(all_data)

具體的日誌 我就不展示了。

交流技術 歡迎+QQ 153132336 zy
個人博客 https://blog.csdn.net/zyooooxie

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章