在Python中使用xlrd读取日期并使用xlsxwriter写入

4 投票
1 回答
4866 浏览
提问于 2025-04-18 05:03

我正在使用xlrd这个工具,从一个Excel表格中读取一堆原始数据,然后进行各种计算和格式调整,最后用xlsxwriter把结果写入一个新的工作簿。

我可以用xlrd正确读取日期数据,并把它转换成日期时间对象,但当我尝试用xlsxwriter写入时却出现了错误。我看过很多关于xlsxwriter和Excel数据格式的帖子,也在网上搜索过,但就是搞不明白。

我的代码是:

in_wb = xlrd.open_workbook("in_book.xlsx")
in_sheet = in_wb.sheet_by_name("in_sheet")

out_wb = xlsxwriter.Workbook("out_book.xlsx")
out_sheet = out_wb.add_worksheet("out_sheet")
date_format = out_wb.add_format({'num_format': 'YYYY-MM-DD HH:DD:SS'})

as_tuple = xlrd.xldate_as_tuple(in_sheet.cell_value(0, 0), in_wb.datemode)
as_datetime = datetime.datetime(as_tuple[0], as_tuple[1], as_tuple[2] , as_tuple[3], as_tuple[4], as_tuple[5])

out_sheet.write_datetime(0, 0, as_datetime, date_format)

#print details just to be sure
print as_datetime #prints it in exactly the format I want
print type(as_datetime) #says it is of type 'datetime.datetime'

完整的错误信息是(不包括我py文件中的第一个调用):

  File "C:\Python27\lib\site-packages\xlsxwriter\worksheet.py", line 57, in cell_wrapper
return method(self, *args, **kwargs)
  File "C:\Python27\lib\site-packages\xlsxwriter\worksheet.py", line 668, in write_datetime
number = self._convert_date_time(date)
  File "C:\Python27\lib\site-packages\xlsxwriter\worksheet.py", line 3267, in _convert_date_time
return datetime_to_excel_datetime(dt_obj, self.date_1904)
  File "C:\Python27\lib\site-packages\xlsxwriter\utility.py", line 576, in datetime_to_excel_datetime
raise TypeError("Unknown or unsupported datetime type")
  TypeError: Unknown or unsupported datetime type
  Exception LookupError: 'unknown encoding: utf-8' in <bound method Workbook.__del__ of <xlsxwriter.workbook.Workbook object at 0x030BAB50>> ignored

当我直接调用普通的'out_sheet.write'时,生成的电子表格中会在单元格里显示一堆'######',但当我点击那个单元格时,它又会显示我想要的日期和时间。我不太确定怎么才能去掉这些'####'。我不在乎用write_datetime()还是write(),我只想让输出表格的单元格正确显示内容。

非常感谢你的帮助!

1 个回答

3

我安装了最新版本的 xlrd(0.9.3)和 xlsxwriter(0.5.3),并且能够顺利运行你的示例程序,没有出现任何错误:

import xlrd
import xlsxwriter
import datetime

in_wb = xlrd.open_workbook("in_book.xlsx")
in_sheet = in_wb.sheet_by_name("in_sheet")

out_wb = xlsxwriter.Workbook("out_book.xlsx")
out_sheet = out_wb.add_worksheet("out_sheet")
date_format = out_wb.add_format({'num_format': 'YYYY-MM-DD HH:DD:SS'})

as_tuple = xlrd.xldate_as_tuple(in_sheet.cell_value(0, 0), in_wb.datemode)
as_datetime = datetime.datetime(as_tuple[0], as_tuple[1], as_tuple[2],
                                as_tuple[3], as_tuple[4], as_tuple[5])

out_sheet.write_datetime(0, 0, as_datetime, date_format)


print as_datetime
print type(as_datetime)

out_wb.close()

需要注意的是,我在最后加了一个 workbook.close(),这样可以避免文件关闭时出现问题,也能让错误信息更清晰。这段代码运行后生成了预期的 xlsx 文件和输出:

$ python so01.py
2014-05-02 00:00:00
<type 'datetime.datetime'> 

另外,从版本 0.93 开始,xlrd 也支持一个 xldate_as_datetime() 的函数。所以你可以更简单地进行转换,如下所示:

as_datetime = xlrd.xldate.xldate_as_datetime(in_sheet.cell_value(0, 0), 
                                             in_wb.datemode)

out_sheet.write_datetime(0, 0, as_datetime, date_format)

最后:

当我只是调用普通的 'out_sheet.write' 时,生成的电子表格在单元格里显示一堆 '######',但是当我点击那个单元格时,它会显示我想要的日期和时间。

这是 Excel 的标准方式,表示这个值太大,无法在单元格中显示(因为上面的日期格式比较长)。如果你用 worksheet.set_column() 调整一下列宽,你应该能看到预期的值。

撰写回答