Как преобразовать xls в xlsx

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

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

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

Ответы

Ответ 1

Я должен был сделать это раньше. Основная идея заключается в использовании модуля 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

Ответ 2

У вас должен быть установлен 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()

Ответ 3

Вот мое решение, не рассматривая шрифты, диаграммы и изображения:

$ 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.

Ответ 4

Я не нашел ни одного ответа здесь 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)

Ответ 5

Ответ Рэя мне очень помог, но для тех, кто ищет простой способ конвертировать все листы из 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, например).

Ответ 6

Я улучшаю производительность для метода @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

Ответ 7

Я попробовал решение @Jhon Anderson, хорошо работает, но получил ошибку "год вне диапазона", когда есть ячейки формата времени, такие как HH: mm: ss without date. Там я снова улучшил алгоритм:

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

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

Ответ 8

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

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

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

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

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

pip install pyexcel-cli pyexcel-xls pyexcel-xlsx

Execute

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

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

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;

Ответ 9

Ответ от Ray был обрезанием первой строки и последнего столбца данных. Вот мое модифицированное решение (для python3):

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+1   #bm added +1
    ncols = sheet.ncols+1   #bm added +1
    index += 1

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

for row in range(1, nrows):
    for col in range(1, ncols):
        sheet1.cell(row=row, column=col).value = sheet.cell_value(row-1, col-1) #bm added -1's

return book1

Ответ 10

Конвертировать XLS файл в XLSX

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

убедитесь, что установили следующие пакеты, прежде чем продолжить

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)

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

xlsarray = sheet.to_array() 

шаг 4: проверить содержимое переменной, чтобы проверить

xlsarray

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

sheet1 = pyexcel.Sheet(xlsarray)

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

sheet1.save_as("test.xlsx")

Ответ 11

Пробовал @Jhon solution 1st, затем я превратился в 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)

Ответ 12

Решение @CaKel и @Jhon Anderson:

def _get_xlrd_cell_value(cell):
    value = cell.value
        if cell.ctype == xlrd.XL_CELL_DATE:
            # Start: if time is 00:00 this fix is necessary
            if value == 1.0:
                datetime_tup = (0, 0, 0)
            else:
            # end
                datetime_tup = xlrd.xldate_as_tuple(value, 0)

            if datetime_tup[0:3] == (0, 0, 0):
                value = datetime.time(*datetime_tup[3:])
            else:
                value = datetime.datetime(*datetime_tup)
    return value

И теперь этот код отлично подходит для меня!