Чтение файлов xlsx с использованием Python

В прошлом году я прочитал, что xlrd обновляется, чтобы читать xlsx файлы (Excel 2007, 2010). Есть ли какие-либо новости об этой разработке или использование других утилит Python?

Ответ 1

Эрик Газони написал openpyxl, который читает/записывает файлы xlsx Более подробную информацию можно найти в его блоге и репозитории кода для любых кодов Python, желающих попробовать.

Ответ 2

Немного поздно, но xlrd теперь поддерживает xlsx. Я обновил от 0.6.0 до 0.8.0 с помощью pip install xlrd --upgrade в командной строке (WindowsKey + R, затем cmd), и теперь он без проблем читает xlsx.

http://pypi.python.org/pypi/xlrd

Ответ 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