В прошлом году я прочитал, что xlrd обновляется, чтобы читать xlsx файлы (Excel 2007, 2010). Есть ли какие-либо новости об этой разработке или использование других утилит Python?
Чтение файлов xlsx с использованием Python
Ответ 1
Эрик Газони написал openpyxl, который читает/записывает файлы xlsx Более подробную информацию можно найти в его блоге и репозитории кода для любых кодов Python, желающих попробовать.
Ответ 2
Немного поздно, но xlrd
теперь поддерживает xlsx
. Я обновил от 0.6.0
до 0.8.0
с помощью pip install xlrd --upgrade
в командной строке (WindowsKey + R, затем cmd
), и теперь он без проблем читает xlsx
.
Ответ 3
Здесь очень грубая реализация, использующая только стандартную библиотеку.
def xlsx(fname):
import zipfile
from xml.etree.ElementTree import iterparse
z = zipfile.ZipFile(fname)
strings = [el.text for e, el in iterparse(z.open('xl/sharedStrings.xml')) if el.tag.endswith('}t')]
rows = []
row = {}
value = ''
for e, el in iterparse(z.open('xl/worksheets/sheet1.xml')):
if el.tag.endswith('}v'): # <v>84</v>
value = el.text
if el.tag.endswith('}c'): # <c r="A3" t="s"><v>84</v></c>
if el.attrib.get('t') == 's':
value = strings[int(value)]
letter = el.attrib['r'] # AZ22
while letter[-1].isdigit():
letter = letter[:-1]
row[letter] = value
value = ''
if el.tag.endswith('}row'):
rows.append(row)
row = {}
return rows
Ответ 4
import openpyxl as px
import numpy as np
W = px.load_workbook('filename.xlsx', use_iterators = True)
p = W.get_sheet_by_name(name = 'Sheet1')
a=[]
for row in p.iter_rows():
for k in row:
a.append(k.internal_value)
# convert list a to matrix (for example 5*6)
aa= np.resize(a, [5, 6])
# save matrix aa as xlsx file
WW=px.Workbook()
pp=WW.get_active_sheet()
pp.title='NEW_DATA'
f={'A':0,'B':1,'C':2,'D':3,'E':4,'F':5}
#insert values in six columns
for (i,j) in f.items():
for k in np.arange(1,len(aa)+1):
pp.cell('%s%d'%(i,k)).value=aa[k-1][j]
WW.save('newfilname.xlsx')
Ответ 5
Поддержка чтения основных данных (open_workbook (..., formatting_info = False)) из файлов Excel.xlsx и .xlsm находится в альфа-тест на данный момент. См. Предыдущие сообщения в этой группе (поиск для "excel 2007 xlsx" ).
Из форума Относительно поддержки xlrd для excel
Ответ 6
Чтение файлов XLSX на самом деле довольно просто.
Они представляют собой ZIP-архивы с определенными документами XML с фиксированными именами.
Вы можете - без особого кода - открыть ZIP-архив, проанализировать соответствующие документы XML и обработать соответствующие биты данных.
Вот несколько советов: http://slott-softwarearchitect.blogspot.com/2010/10/xlsm-and-xlsx-files-finally-reaching.html
Ответ 7
Да, спасибо за отличную подпрограмму!
Я обновил его, чтобы позволить хешам строк использовать имена столбцов в качестве индекса вместо букв, если указана строка заголовка.
readXlsx( "mysheet.xlsx", sheet = 1, header = True )
def readXlsx( fileName, **args ):
import zipfile
from xml.etree.ElementTree import iterparse
if "sheet" in args:
sheet=args["sheet"]
else:
sheet=1
if "header" in args:
isHeader=args["header"]
else:
isHeader=False
rows = []
row = {}
header = {}
z = zipfile.ZipFile( fileName )
# Get shared strings
strings = [ el.text for e, el
in iterparse( z.open( 'xl/sharedStrings.xml' ) )
if el.tag.endswith( '}t' )
]
value = ''
# Open specified worksheet
for e, el in iterparse( z.open( 'xl/worksheets/sheet%d.xml'%( sheet ) ) ):
# get value or index to shared strings
if el.tag.endswith( '}v' ): # <v>84</v>
value = el.text
if el.tag.endswith( '}c' ): # <c r="A3" t="s"><v>84</v></c>
# If value is a shared string, use value as an index
if el.attrib.get( 't' ) == 's':
value = strings[int( value )]
# split the row/col information so that the row leter(s) can be separate
letter = el.attrib['r'] # AZ22
while letter[-1].isdigit():
letter = letter[:-1]
# if it is the first row, then create a header hash for the names
# that COULD be used
if rows ==[]:
header[letter]=value
else:
if value != '':
# if there is a header row, use the first row names as the row hash index
if isHeader == True and letter in header:
row[header[letter]] = value
else:
row[letter] = value
value = ''
if el.tag.endswith('}row'):
rows.append(row)
row = {}
z.close()
return rows