手上的某些需求 用到xlsx格式的Excel的生成、解析,之前分享过: Excel大数据量的读写、 Excel的读写,这儿说下,关于日期格式的处理。
个人博客:https://blog.csdn.net/zyooooxie
需求
假设要用的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