簡體   English   中英

python xlrd可以更改.xlsx文件中的列類型嗎

[英]can python xlrd change a column type in an .xlsx file

我想使用xlrd讀取一組由其他人創建的.xlsx文件集,這些人不幸地錯誤地格式化了Excel中的列。 該列是節標簽(文本),例如1.2.3.4。 但是它被格式化為日期。 它在Excel中顯示為OK,但是當我嘗試使用xlrd讀取它時,它將作為日期讀取。 我嘗試了“ converters = {'Section':str}”,但是遇到了錯誤

OverflowError:歸一化的天數太大,無法容納C int

(所討論的單元格沒有條目。)

我已經閱讀了一些,但是找不到修復.xlsx文件的好方法,以便使列具有正確的數據類型。

如何修復或讀取.xlsx文件,以便可以正確讀取數據類型而不會出現錯誤。

在Excel中,如果單元格的格式設置為日期,則將其存儲為浮點數。 (請參閱Excel電子表格中的日期 )。

因此,原始輸入數據將丟失。 唯一存儲的是浮點數,它在加載時由Excel重新構造。

您可以通過打印單元格內容來驗證這一點。 如果由於某種原因您不能這樣做(您說這會導致錯誤),則可以獲取單元格並將文本的ctype屬性更改為1。 例如:

cell = sheet.cell(r,c)
print(cell)    # xldate:37623.0  (if this causes an error, comment it out)
cell.ctype = 1
print(cell)    # text:37623.0

可能能夠做的就是通過xlrd.xldate_as_tuple將浮點數轉換為元組來xlrd.xldate_as_tuple原始值

cell = sheet.cell(r,c)
print(cell)
print(xlrd.xldate_as_tuple(cell.value, workbook.datemode))

輸出示例:

1/2/3                  # Entered in cell
xldate:37623.0         # print(cell)
(2003, 1, 2, 0, 0, 0)  # print(xlrd.xldate_as_tuple(...))

1/2/3                  # Entered in cell
xldate:38415.0         # print(cell)
(2003, 1, 2, 0, 0, 0)  # print(xlrd.xldate_as_tuple(...))

一旦弄清楚了元組元素和Excel顯示的數據之間的關系,就可以直接對元組的數據進行操作。

如果這不起作用,則最小化的最小示例.xls文件將有助於進一步診斷。

注意:這是使用xlrd 0.9.3版編寫的。 在上面的示例中, workbook是保存workbook的變量(例如,通過xlrd.open_workbook ),而工作sheet是保存工作表的變量(例如,通過workbook.sheet_by_index )。


更新:根據評論中的討論,您可以執行以下操作:

import xlrd

workbook = xlrd.open_workbook('file.xlsx', ragged_rows=True)
sheet = workbook.sheet_by_index(0)

def safe_cell(cell):
    try:
        str(cell)
    except ValueError:
        cell.ctype = 1
    return cell

def safe_get(sheet, r, c):
    cell = sheet.cell(r,c)
    return safe_cell(cell)

然后使用以下方法之一訪問單元:

# Approach (a)
for r in sheet.nrows:
    for c in sheet.ncols:
        cell = safe_get(sheet, r, c)
        # You can now operate on cell without worrying about it raising a ValueError

# Approach (b)
for r in sheet.nrows:
    for cell in sheet.row(r):
        cell = safe_cell(cell)
        # You can now operate on cell without worrying about it raising a ValueError

可能可以執行以下操作:

for r in sheet.nrows:
    for cell in sheet.row(r):
        try:
            str(cell)
        except ValueError:
            cell.ctype = 1

一次,在腳本的開頭,它可能會 “修復”您以后要閱讀的單元格,但是由於我無法重現您的問題,因此無法保證。

如果這不起作用,則可以使用兩種方法之一(使用safe_*函數),但是您需要在從工作表訪問單元格的任何地方使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM