как конвертировать xls в xlsx - PullRequest
19 голосов
/ 29 марта 2012

У меня есть несколько * .xls (Excel 2003) файлов ,, и я хочу преобразовать эти файлы в xlsx (Excel 2007).

Я использую пакет uno python, когда я сохраняю документы, Я могу установить имя фильтра: MS Excel 97 Но нет имени фильтра, например «MS Excel 2007»,

, пожалуйста, помогите мне, как установить имя фильтра для преобразования xls в xlsx?

Ответы [ 11 ]

17 голосов
/ 29 марта 2012

Я должен был сделать это раньше. Основная идея заключается в том, чтобы использовать модуль xlrd , чтобы открывать и анализировать файл xls и записывать содержимое файла xlsx с использованием модуля openpyxl .

Вот мой код. Внимание! Он не может обрабатывать сложные файлы xls, вы должны добавить собственную логику синтаксического анализа, если вы собираетесь ее использовать.

import xlrd
from openpyxl.workbook import Workbook
from openpyxl.reader.excel import load_workbook, InvalidFileException

def open_xls_as_xlsx(filename):
    # first open using xlrd
    book = xlrd.open_workbook(filename)
    index = 0
    nrows, ncols = 0, 0
    while nrows * ncols == 0:
        sheet = book.sheet_by_index(index)
        nrows = sheet.nrows
        ncols = sheet.ncols
        index += 1

    # prepare a xlsx sheet
    book1 = Workbook()
    sheet1 = book1.get_active_sheet()

    for row in xrange(0, nrows):
        for col in xrange(0, ncols):
            sheet1.cell(row=row, column=col).value = sheet.cell_value(row, col)

    return book1
12 голосов
/ 10 апреля 2017

Вот мое решение, без учета шрифтов, диаграмм и изображений:

$ pip install pyexcel pyexcel-xls pyexcel-xlsx

Тогда сделайте это: *

import pyexcel as p

p.save_book_as(file_name='your-file-in.xls',
               dest_file_name='your-new-file-out.xlsx')

Если вам не нужна программа, вы можете установитьодин дополнительный пакет pyexcel-cli ::

$ pip install pyexcel-cli
$ pyexcel transcode your-file-in.xls your-new-file-out.xlsx

Приведенная выше процедура транскодирования использует xlrd и openpyxl.

11 голосов
/ 29 июня 2014

На вашем компьютере должен быть установлен win32com. Вот мой код:

import win32com.client as win32
fname = "full+path+to+xls_file"
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Open(fname)

wb.SaveAs(fname+"x", FileFormat = 51)    #FileFormat = 51 is for .xlsx extension
wb.Close()                               #FileFormat = 56 is for .xls extension
excel.Application.Quit()
9 голосов
/ 13 сентября 2016

Я не нашел здесь ни одного ответа на 100% правильно.Поэтому я выкладываю свои коды здесь:

import xlrd
from openpyxl.workbook import Workbook

def cvt_xls_to_xlsx(src_file_path, dst_file_path):
    book_xls = xlrd.open_workbook(src_file_path)
    book_xlsx = Workbook()

    sheet_names = book_xls.sheet_names()
    for sheet_index in range(0,len(sheet_names)):
        sheet_xls = book_xls.sheet_by_name(sheet_names[sheet_index])
        if sheet_index == 0:
            sheet_xlsx = book_xlsx.active()
            sheet_xlsx.title = sheet_names[sheet_index]
        else:
            sheet_xlsx = book_xlsx.create_sheet(title=sheet_names[sheet_index])

        for row in range(0, sheet_xls.nrows):
            for col in range(0, sheet_xls.ncols):
                sheet_xlsx.cell(row = row+1 , column = col+1).value = sheet_xls.cell_value(row, col)

    book_xlsx.save(dst_file_path)
6 голосов
/ 10 июня 2015

Ответ Рэя мне очень помог, но для тех, кто ищет простой способ конвертировать все листы из xls в xlsx, я сделал это Gist :

import xlrd
from openpyxl.workbook import Workbook as openpyxlWorkbook

# content is a string containing the file. For example the result of an http.request(url).
# You can also use a filepath by calling "xlrd.open_workbook(filepath)".

xlsBook = xlrd.open_workbook(file_contents=content)
workbook = openpyxlWorkbook()

for i in xrange(0, xlsBook.nsheets):
    xlsSheet = xlsBook.sheet_by_index(i)
    sheet = workbook.active if i == 0 else workbook.create_sheet()
    sheet.title = xlsSheet.name

    for row in xrange(0, xlsSheet.nrows):
        for col in xrange(0, xlsSheet.ncols):
            sheet.cell(row=row, column=col).value = xlsSheet.cell_value(row, col)

# The new xlsx file is in "workbook", without iterators (iter_rows).
# For iteration, use "for row in worksheet.rows:".
# For range iteration, use "for row in worksheet.range("{}:{}".format(startCell, endCell)):".

Вы можете найти xlrd lib здесь и openpyxl здесь (например, вы должны загрузить xlrd в своем проекте для Google App Engine).

4 голосов
/ 03 марта 2017

Я улучшаю производительность для метода @Jackypengyu.

Объединенные ячейки также будут преобразованы.

Результаты

Конвертировать те же 12 файлов в том же порядке:

Оригинал :

0:00:01.958159
0:00:02.115891
0:00:02.018643
0:00:02.057803
0:00:01.267079
0:00:01.308073
0:00:01.245989
0:00:01.289295
0:00:01.273805
0:00:01.276003
0:00:01.293834
0:00:01.261401

Улучшено :

0:00:00.774101
0:00:00.734749
0:00:00.741434
0:00:00.744491
0:00:00.320796
0:00:00.279045
0:00:00.315829
0:00:00.280769
0:00:00.316380
0:00:00.289196
0:00:00.347819
0:00:00.284242

Решение

def cvt_xls_to_xlsx(*args, **kw):
    """Open and convert XLS file to openpyxl.workbook.Workbook object

    @param args: args for xlrd.open_workbook
    @param kw: kwargs for xlrd.open_workbook
    @return: openpyxl.workbook.Workbook


    You need -> from openpyxl.utils.cell import get_column_letter
    """

    book_xls = xlrd.open_workbook(*args, formatting_info=True, ragged_rows=True, **kw)
    book_xlsx = Workbook()

    sheet_names = book_xls.sheet_names()
    for sheet_index in range(len(sheet_names)):
        sheet_xls = book_xls.sheet_by_name(sheet_names[sheet_index])

        if sheet_index == 0:
            sheet_xlsx = book_xlsx.active
            sheet_xlsx.title = sheet_names[sheet_index]
        else:
            sheet_xlsx = book_xlsx.create_sheet(title=sheet_names[sheet_index])

        for crange in sheet_xls.merged_cells:
            rlo, rhi, clo, chi = crange

            sheet_xlsx.merge_cells(
                start_row=rlo + 1, end_row=rhi,
                start_column=clo + 1, end_column=chi,
            )

        def _get_xlrd_cell_value(cell):
            value = cell.value
            if cell.ctype == xlrd.XL_CELL_DATE:
                value = datetime.datetime(*xlrd.xldate_as_tuple(value, 0))

            return value

        for row in range(sheet_xls.nrows):
            sheet_xlsx.append((
                _get_xlrd_cell_value(cell)
                for cell in sheet_xls.row_slice(row, end_colx=sheet_xls.row_len(row))
            ))

        for rowx in range(sheet_xls.nrows):
            if sheet_xls.rowinfo_map[rowx].hidden != 0:
                print sheet_names[sheet_index], rowx
                sheet_xlsx.row_dimensions[rowx+1].hidden = True
        for coly in range(sheet_xls.ncols):
            if sheet_xls.colinfo_map[coly].hidden != 0:
                print sheet_names[sheet_index], coly
                coly_letter = get_column_letter(coly+1)
                sheet_xlsx.column_dimensions[coly_letter].hidden = True

    return book_xlsx
2 голосов
/ 05 сентября 2017

Простое решение

Мне потребовалось простое решение для преобразования пары xlx в xlsx формат.Здесь есть множество ответов, но они совершают «магию», которую я не до конца понимаю.

Простое решение было дано chfw , но не совсем полное.

Установить зависимости

Используйте pip для установки

pip install pyexcel-cli pyexcel-xls pyexcel-xlsx

Выполнить

Все стили и макросы будут удалены, но информация не повреждена.

Для одного файла

pyexcel transcode your-file-in.xls your-new-file-out.xlsx

Для всех файлов в папке один вкладыш

for file in *.xls; do; echo "Transcoding $file"; pyexcel transcode "$file" "${file}x"; done;
1 голос
/ 15 мая 2017

Я попробовал решение @Jhon Anderson, оно работает хорошо, но получило ошибку «год вне диапазона», когда есть ячейки формата времени, такие как ЧЧ: мм: сс без даты. Я снова улучшил алгоритм:

def xls_to_xlsx(*args, **kw):
"""
    open and convert an XLS file to openpyxl.workbook.Workbook
    ----------
    @param args: args for xlrd.open_workbook
    @param kw: kwargs for xlrd.open_workbook
    @return: openpyxl.workbook.Workbook对象
    """
    book_xls = xlrd.open_workbook(*args, formatting_info=True, ragged_rows=True, **kw)
    book_xlsx = openpyxl.workbook.Workbook()

    sheet_names = book_xls.sheet_names()
    for sheet_index in range(len(sheet_names)):
        sheet_xls = book_xls.sheet_by_name(sheet_names[sheet_index])
        if sheet_index == 0:
            sheet_xlsx = book_xlsx.active
            sheet_xlsx.title = sheet_names[sheet_index]
        else:
            sheet_xlsx = book_xlsx.create_sheet(title=sheet_names[sheet_index])
        for crange in sheet_xls.merged_cells:
            rlo, rhi, clo, chi = crange
            sheet_xlsx.merge_cells(start_row=rlo + 1, end_row=rhi,
            start_column=clo + 1, end_column=chi,)

        def _get_xlrd_cell_value(cell):
            value = cell.value
            if cell.ctype == xlrd.XL_CELL_DATE:
                datetime_tup = xlrd.xldate_as_tuple(value,0)    
                if datetime_tup[0:3] == (0, 0, 0):   # time format without date
                    value = datetime.time(*datetime_tup[3:])
                else:
                    value = datetime.datetime(*datetime_tup)
            return value

        for row in range(sheet_xls.nrows):
            sheet_xlsx.append((
                _get_xlrd_cell_value(cell)
                for cell in sheet_xls.row_slice(row, end_colx=sheet_xls.row_len(row))
            ))
    return book_xlsx

Тогда работай идеально!

0 голосов
/ 10 июня 2019

Пробовал решение @ Jhon 1-го, затем я превратил в pyexcel в качестве решения

pyexcel.save_as(file_name=oldfilename, dest_file_name=newfilename)

Он работал правильно, пока я не попытался упаковать свой проект в один exe-файл PyInstaller, я попробовал все скрытые опции импорта, следующая ошибка все еще там:

  File "utils.py", line 27, in __enter__
    pyexcel.save_as(file_name=self.filename, dest_file_name=newfilename)
  File "site-packages\pyexcel\core.py", line 77, in save_as
  File "site-packages\pyexcel\internal\core.py", line 22, in get_sheet_stream
  File "site-packages\pyexcel\plugins\sources\file_input.py", line 39, in get_da
ta
  File "site-packages\pyexcel\plugins\parsers\excel.py", line 19, in parse_file
  File "site-packages\pyexcel\plugins\parsers\excel.py", line 40, in _parse_any
  File "site-packages\pyexcel_io\io.py", line 73, in get_data
  File "site-packages\pyexcel_io\io.py", line 91, in _get_data
  File "site-packages\pyexcel_io\io.py", line 188, in load_data
  File "site-packages\pyexcel_io\plugins.py", line 90, in get_a_plugin
  File "site-packages\lml\plugin.py", line 290, in load_me_now
  File "site-packages\pyexcel_io\plugins.py", line 107, in raise_exception
pyexcel_io.exceptions.SupportingPluginAvailableButNotInstalled: Please install p
yexcel-xls
[3192] Failed to execute script

Затем я прыгнул на панд:

pd.read_excel(oldfilename).to_excel(newfilename, sheet_name=self.sheetname,index=False)
0 голосов
/ 15 марта 2018

CONVERT XLS FILE TO XLSX

Использование python3.6 Я только что столкнулся с той же проблемой, и после нескольких часов борьбы я решил ее, выполнив ff, вам, вероятно, не понадобятся все пакеты: (Iбудет так же ясно, как и возможно)

перед установкой обязательно установите следующие пакеты

pip install pyexcel, pip install pyexcel-xls, pip install pyexcel-xlsx,

pip install pyexcel-cli

шаг 1:

import pyexcel

шаг 2: "example.xls", "example.xlsx", "example.xlsm "

sheet0 = pyexcel.get_sheet(file_name="your_file_path.xls", name_columns_by_row=0)

step3: создать массив из содержимого

xlsarray = sheet.to_array() 

step4: проверить содержимое переменной для проверки

xlsarray

step5: передать массив, содержащийся в переменной с именем (xlsarray), в новую переменную книги с именем (sheet1)

sheet1 = pyexcel.Sheet(xlsarray)

step6: сохранитьновый лист, заканчивающийся на .xlsx (в моем случае я хочу xlsx)

sheet1.save_as("test.xlsx")
...