【问题标题】:Converting XLSX to CSV while maintaining timestamps在保持时间戳的同时将 XLSX 转换为 CSV
【发布时间】:2014-09-28 17:29:03
【问题描述】:

我正在尝试将一个充满 XLSX 文件的目录转换为 CSV。一切正常,除了我遇到包含时间信息的列的问题。 XLSX 文件是由另一个我无法修改的程序创建的。但我想保持在 Excel 中查看 XLSX 文件时显示的时间与将其转换为 CSV 并在任何文本编辑器中查看时显示的时间相同。

我的代码:

import csv
import xlrd
import os
import fnmatch
import Tkinter, tkFileDialog, tkMessageBox

def main():
    root = Tkinter.Tk()
    root.withdraw()
    print 'Starting .xslx to .csv conversion'
    directory = tkFileDialog.askdirectory()
    for fileName in os.listdir(directory):
        if fnmatch.fnmatch(fileName, '*.xlsx'):
            filePath = os.path.join(directory, fileName)
            saveFile = os.path.splitext(filePath)[0]+".csv"
            savePath = os.path.join(directory, saveFile)
            workbook = xlrd.open_workbook(filePath)
            sheet = workbook.sheet_by_index(0)
            csvOutput = open(savePath, 'wb')
            csvWriter = csv.writer(csvOutput, quoting=csv.QUOTE_ALL)
            for row in xrange(sheet.nrows):
                csvWriter.writerow(sheet.row_values(row))
            csvOutput.close()
    print '.csv conversion complete'

main()

添加一些细节,如果我在 Excel 中打开一个文件,我会在时间列中看到:

00:10.3
00:14.2
00:16.1
00:20.0
00:22.0

但在我转换为 CSV 后,我在同一位置看到了这个:

0.000118981
0.000164005
0.000186227
0.000231597
0.000254861

感谢 seanmhanson 的回答 https://stackoverflow.com/a/25149562/1858351 我能够弄清楚 Excel 将时间转储为一天的小数。虽然我应该尝试更好地学习和使用 xlrd,但为了快速进行短期修复,我能够将其转换为秒,然后从秒转换回最初看到的 HH:MM:SS 时间格式。我的(可能是丑陋的)代码如下,以防任何人都可以使用它:

import csv
import xlrd
import os
import fnmatch
from decimal import Decimal
import Tkinter, tkFileDialog

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

def seconds_to_hms(seconds):
    input = Decimal(seconds)
    m, s = divmod(input, 60)
    h, m = divmod(m, 60)
    hm = "%02d:%02d:%02.2f" % (h, m, s)
    return hm

def main():
    root = Tkinter.Tk()
    root.withdraw()
    print 'Starting .xslx to .csv conversion'
    directory = tkFileDialog.askdirectory()
    for fileName in os.listdir(directory):
        if fnmatch.fnmatch(fileName, '*.xlsx'):
            filePath = os.path.join(directory, fileName)
            saveFile = os.path.splitext(filePath)[0]+".csv"
            savePath = os.path.join(directory, saveFile)
            workbook = xlrd.open_workbook(filePath)
            sheet = workbook.sheet_by_index(0)
            csvOutput = open(savePath, 'wb')
            csvWriter = csv.writer(csvOutput, quoting=csv.QUOTE_ALL)
            rowData = []
            for rownum in range(sheet.nrows):
                rows = sheet.row_values(rownum)
                for cell in rows:
                    if is_number(cell):
                        seconds = float(cell)*float(86400)
                        hms = seconds_to_hms(seconds)
                        rowData.append((hms))
                    else:
                        rowData.append((cell))
                csvWriter.writerow(rowData)
                rowData = []
            csvOutput.close()
    print '.csv conversion complete'

main()

【问题讨论】:

  • 您是否尝试在导出之前将时间列转换为纯文本?
  • @VanCowboy 问题在于 excel 提供了基础数据的格式化视图。原始数据实际上是小数,所以我认为转换为纯文本不会解决我的问题。我在下面选择的答案更好地解释了这一点,我改变了我的代码来解决上面的问题

标签: python excel csv time xlsx


【解决方案1】:

Excel 将时间存储为以天为单位的浮点数。您将需要使用 XLRD 来确定单元格是否为日期,然后根据需要进行转换。我不喜欢 XLRD,但你可能想要类似的东西,如果你想保持前导零,请更改字符串格式:

if cell.ctype == xlrd.XL_CELL_DATE:
    try: 
        cell_tuple = xldate_as_tuple(cell, 0)
        return "{hours}:{minutes}:{seconds}".format(
            hours=cell_tuple[3], minutes=cell_tuple[4], seconds=cell_tuple[5])
    except (any exceptions thrown by xldate_as_tuple):
        //exception handling

XLRD date to tuple 方法的文档可以在这里找到:https://secure.simplistix.co.uk/svn/xlrd/trunk/xlrd/doc/xlrd.html?p=4966#xldate.xldate_as_tuple-function

对于已经回答的类似问题,另请参阅此问题:Python: xlrd discerning dates from floats

【讨论】:

  • 您的回答帮助我解决了我的问题,所以我将其标记为这样。我最终选择了一条不同的路线,这对我来说实现起来更快(上面发布的代码就是这样),但从长远来看,我可能应该学会更好地使用 xlrd。
  • 是的,我同意上述方法绝对不是满足您需求的最佳解决方案,(我只是乘以然后格式化秒数)但很高兴知道它存在/存在您应该检查 XLRD 的方法。如果你做了其他事情,你应该发布它!
  • xlrd 0.9.3 于 2014 年 4 月发布,它包含函数 xldate.xldate_as_datetime,可将 Excel 日期直接转换为 Python 日期时间。尽管如此,这是一个相对较小的便利,因为从元组创建日期、时间或日期时间很容易。主要要知道的是 Python 提供了一个方法,strftime,它可以很容易地转换成各种格式的字符串。
猜你喜欢
  • 2020-06-08
  • 2020-11-07
  • 1970-01-01
  • 2020-07-06
  • 2021-07-21
  • 1970-01-01
  • 2022-07-20
  • 2020-10-17
  • 1970-01-01
相关资源
最近更新 更多