Wypróbowałem xlrd, pandas, openpyxl i inne tego typu biblioteki i wszystkie z nich wydają się zajmować wykładniczy czas, ponieważ rozmiar pliku rośnie, gdy odczytuje cały plik. Inne wymienione powyżej rozwiązania, w których używali „on_demand”, nie działały u mnie. Jeśli chcesz tylko początkowo uzyskać nazwy arkuszy, następująca funkcja działa dla plików xlsx.
def get_sheet_details(file_path):
sheets = []
file_name = os.path.splitext(os.path.split(file_path)[-1])[0]
# Make a temporary directory with the file name
directory_to_extract_to = os.path.join(settings.MEDIA_ROOT, file_name)
os.mkdir(directory_to_extract_to)
# Extract the xlsx file as it is just a zip file
zip_ref = zipfile.ZipFile(file_path, 'r')
zip_ref.extractall(directory_to_extract_to)
zip_ref.close()
# Open the workbook.xml which is very light and only has meta data, get sheets from it
path_to_workbook = os.path.join(directory_to_extract_to, 'xl', 'workbook.xml')
with open(path_to_workbook, 'r') as f:
xml = f.read()
dictionary = xmltodict.parse(xml)
for sheet in dictionary['workbook']['sheets']['sheet']:
sheet_details = {
'id': sheet['@sheetId'],
'name': sheet['@name']
}
sheets.append(sheet_details)
# Delete the extracted files directory
shutil.rmtree(directory_to_extract_to)
return sheets
Ponieważ wszystkie xlsx są w zasadzie spakowanymi plikami, wyodrębniamy podstawowe dane xml i czytamy nazwy arkuszy bezpośrednio ze skoroszytu, co zajmuje ułamek sekundy w porównaniu z funkcjami biblioteki.
Benchmarking: (na pliku 6mb xlsx z 4 arkuszami)
Pandy, xlrd: 12 sekund
openpyxl: 24 sekundy
Proponowana metoda: 0,4 sekundy
Ponieważ moim wymaganiem było po prostu czytanie nazw arkuszy, niepotrzebne obciążenie związane z czytaniem przez cały czas mnie niepokoiło, więc zamiast tego wybrałem tę trasę.
ExcelFile
? Powiedzmy również, że przeglądam listę arkuszy i decyduję się załadować N z nich. Czy powinienem w tym momencie wywołaćread_excel
(nowy interfejs) dla każdego arkusza, czy trzymać sięx1.parse
?