Pisanie do arkusza kalkulacyjnego Excel

149

Jestem nowy w Pythonie. Muszę zapisać dane z mojego programu do arkusza kalkulacyjnego. Szukałem online i wydaje mi się, że jest dostępnych wiele pakietów (xlwt, XlsXcessive, openpyxl). Inni sugerują, aby pisać do pliku .csv (nigdy nie używali CSV i tak naprawdę nie rozumieją, co to jest).

Program jest bardzo prosty. Mam dwie listy (float) i trzy zmienne (stringi). Nie znam długości obu list i prawdopodobnie nie będą one tej samej długości.

Chcę, żeby układ był taki jak na poniższym obrazku:

Przykładowy układ

Różowa kolumna będzie zawierać wartości z pierwszej listy, a zielona kolumna - wartości z drugiej listy.

Więc jaki jest najlepszy sposób, aby to zrobić?

PS Używam systemu Windows 7, ale niekoniecznie będę mieć zainstalowany pakiet Office na komputerach z tym programem.

import xlwt

x=1
y=2
z=3

list1=[2.34,4.346,4.234]

book = xlwt.Workbook(encoding="utf-8")

sheet1 = book.add_sheet("Sheet 1")

sheet1.write(0, 0, "Display")
sheet1.write(1, 0, "Dominance")
sheet1.write(2, 0, "Test")

sheet1.write(0, 1, x)
sheet1.write(1, 1, y)
sheet1.write(2, 1, z)

sheet1.write(4, 0, "Stimulus Time")
sheet1.write(4, 1, "Reaction Time")

i=4

for n in list1:
    i = i+1
    sheet1.write(i, 0, n)



book.save("trial.xls")

Napisałem to korzystając ze wszystkich twoich sugestii. Wykonuje swoją pracę, ale można ją nieco poprawić.

Jak sformatować komórki utworzone w pętli for (wartości listy1) jako naukowe lub liczbowe?

Nie chcę skracać wartości. Rzeczywiste wartości używane w programie miałyby około 10 cyfr po przecinku.

Jey
źródło
Zrozumiesz, czym jest plik tsv, jeśli otworzysz go w edytorze tekstu, takim jak Notatnik / Wordpad. Kluczową zaletą korzystania z tsv jest to, że możesz mieć pewność, że można go otworzyć w zasadzie każda wersja dowolnego programu do obsługi arkuszy kalkulacyjnych, a nie tylko program Excel pakietu Office 2010
goncalopp
Użyj formatu łańcuchowego w Pythonie, aby kontrolować wyświetlanie danych liczbowych.
Fred Mitchell
sprawdź, czy openpyxl pracuje z plikami .xlsx
Santiago,

Odpowiedzi:

95
import xlwt

def output(filename, sheet, list1, list2, x, y, z):
    book = xlwt.Workbook()
    sh = book.add_sheet(sheet)

    variables = [x, y, z]
    x_desc = 'Display'
    y_desc = 'Dominance'
    z_desc = 'Test'
    desc = [x_desc, y_desc, z_desc]

    col1_name = 'Stimulus Time'
    col2_name = 'Reaction Time'

    #You may need to group the variables together
    #for n, (v_desc, v) in enumerate(zip(desc, variables)):
    for n, v_desc, v in enumerate(zip(desc, variables)):
        sh.write(n, 0, v_desc)
        sh.write(n, 1, v)

    n+=1

    sh.write(n, 0, col1_name)
    sh.write(n, 1, col2_name)

    for m, e1 in enumerate(list1, n+1):
        sh.write(m, 0, e1)

    for m, e2 in enumerate(list2, n+1):
        sh.write(m, 1, e2)

    book.save(filename)

więcej wyjaśnień: https://github.com/python-excel

thkang
źródło
13
Możesz chcieć wspomnieć, że jeśli używasz Pythona w systemie Windows i masz zainstalowany program Excel na tym samym komputerze, możesz użyć interfejsu Python COM do bezpośredniego sterowania programem Excel.
Michael Dillon,
1
Link był bardzo pomocny. Dzięki
Jey,
3
Zwróć uwagę, że przy tym kodzie maksymalny limit wierszy to 65536 wierszy, ponieważ pliki .xls obsługują tylko tyle wierszy
Shreyas Pimpalgaonkar
1
Żeby było jasne, xlwtsłuży tylko do zapisywania starych .xlsplików dla programu Excel 2003 lub wcześniejszego. Może to być nieaktualne (w zależności od Twoich potrzeb).
cowlinator
Możesz sprawdzić, czy openpyxl działa z plikami .xlsx
Santiago,
140

Użyj DataFrame.to_excel z pand . Pandy pozwalają na reprezentowanie danych w bogatych funkcjonalnie strukturach danych i umożliwiają czytanie również w plikach Excel.

Najpierw musisz przekonwertować dane na ramkę DataFrame, a następnie zapisać je w pliku Excela, jak poniżej:

In [1]: from pandas import DataFrame
In [2]: l1 = [1,2,3,4]
In [3]: l2 = [1,2,3,4]
In [3]: df = DataFrame({'Stimulus Time': l1, 'Reaction Time': l2})
In [4]: df
Out[4]: 
   Reaction Time  Stimulus Time
0              1              1
1              2              2
2              3              3
3              4              4

In [5]: df.to_excel('test.xlsx', sheet_name='sheet1', index=False)

a plik Excela, który się pojawi, wygląda następująco:

wprowadź opis obrazu tutaj

Pamiętaj, że obie listy muszą mieć taką samą długość, w przeciwnym razie pandy będą narzekać. Aby rozwiązać ten problem, zamień wszystkie brakujące wartości na None.

diliop
źródło
Dziękuję, ale wydaje się to zbyt skomplikowane dla moich potrzeb.
Jey,
Niezły, ale trochę przesadzony +1
Burhan Khalid
2
Jestem całkiem pewien, że pandy używają bibliotek xlrd / xlwt do swoich możliwości programu
mrmagooey
6
Zakładałem, że to xlwtteż jest używane , ale otrzymuję openpyxlbłąd. Dla każdego, kto jest przez to zdezorientowany - wszystko jest w żądanym typie pliku. Dokumentacja pandy (0.12) mówi: „Pliki z .xlsrozszerzeniem zostaną zapisane przy użyciu xlwt, a te z .xlsxrozszerzeniem zostaną zapisane przy użyciu openpyxl”.
Racing Tadpole
5
Nie wiem, dlaczego ludzie mówią, że to przesada. Dla moich celów było to właśnie to, czego szukałem. Dzięki!
Abe,
35
  • xlrd / xlwt (standard): Python nie ma tej funkcjonalności w swojej bibliotece standardowej, ale myślę o xlrd / xlwt jako o „standardowym” sposobie odczytu i zapisu plików Excela. Tworzenie skoroszytu, dodawanie arkuszy, zapisywanie danych / formuł i formatowanie komórek jest dość łatwe. Jeśli potrzebujesz wszystkich tych rzeczy, możesz odnieść największy sukces z tą biblioteką. Myślę, że mógłbyś zamiast tego wybrać openpyxl i byłoby to całkiem podobne, ale ja go nie używałem.

    Aby sformatować komórki za pomocą xlwt, zdefiniuj a XFStylei dołącz styl podczas pisania do arkusza. Oto przykład z wieloma formatami liczb . Zobacz przykładowy kod poniżej.

  • Tablib (potężny, intuicyjny): Tablib to bardziej wydajna, ale intuicyjna biblioteka do pracy z danymi tabelarycznymi. Może pisać skoroszyty programu Excel z wieloma arkuszami, a także innymi formatami, takimi jak csv, json i yaml. Jeśli nie potrzebujesz sformatowanych komórek (takich jak kolor tła), zrobisz sobie przysługę, korzystając z tej biblioteki, co na dłuższą metę pozwoli Ci dotrzeć dalej.

  • csv (łatwy): Pliki na twoim komputerze są w formacie tekstowym lub binarnym . Pliki tekstowe to tylko znaki, w tym znaki specjalne, takie jak nowe linie i tabulatory, i można je łatwo otwierać w dowolnym miejscu (np. W notatniku, przeglądarce internetowej lub w produktach pakietu Office). Plik CSV to plik tekstowy sformatowany w określony sposób: każda linia to lista wartości oddzielonych przecinkami. Programy w języku Python mogą z łatwością odczytywać i zapisywać tekst, więc plik csv jest najłatwiejszym i najszybszym sposobem na wyeksportowanie danych z programu w języku Python do programu Excel (lub innego programu w języku Python).

    Pliki Excel są binarne i wymagają specjalnych bibliotek, które znają format plików, dlatego do ich odczytu / zapisu potrzebujesz dodatkowej biblioteki dla języka Python lub specjalnego programu, takiego jak Microsoft Excel, Gnumeric lub LibreOffice.


import xlwt

style = xlwt.XFStyle()
style.num_format_str = '0.00E+00'

...

for i,n in enumerate(list1):
    sheet1.write(i, 0, n, fmt)
jmilloy
źródło
2
Prawdopodobnie będziesz chciał użyć modułu csv zawartego w standardowej bibliotece, jeśli zamierzasz napisać plik CSV.
Flimm
1
Nie żeby to miało szczególne znaczenie, ale Tablib, podobnie jak wiele innych pakietów wyższego poziomu, używa xlwt do tworzenia plików Excela.
John Y
13

Przeanalizowałem kilka modułów Excela dla Pythona i odkryłem, że openpyxl jest najlepszy.

Bezpłatna książka Automate the Boring Stuff with Python zawiera rozdział o openpyxl zawierający więcej szczegółów lub możesz sprawdzić stronę Read the Docs . Nie będziesz potrzebować zainstalowanego pakietu Office ani Excel, aby korzystać z openpyxl.

Twój program wyglądałby mniej więcej tak:

import openpyxl
wb = openpyxl.load_workbook('example.xlsx')
sheet = wb.get_sheet_by_name('Sheet1')

stimulusTimes = [1, 2, 3]
reactionTimes = [2.3, 5.1, 7.0]

for i in range(len(stimulusTimes)):
    sheet['A' + str(i + 6)].value = stimulusTimes[i]
    sheet['B' + str(i + 6)].value = reactionTimes[i]

wb.save('example.xlsx')
Al Sweigart
źródło
Pojawia się błąd mówiący: nie można przekonwertować int64 na excel
pnkjmndhl
11

CSV oznacza wartości oddzielone przecinkami. CSV jest jak plik tekstowy i można go utworzyć, dodając po prostu rozszerzenie .CSV

na przykład napisz ten kod:

f = open('example.csv','w')
f.write("display,variable x")
f.close()

możesz otworzyć ten plik w programie Excel.

2 8
źródło
5
Nie można formatować tła kolumn za pomocą CSV. Jest to tylko format danych do importu i eksportu.
Michael Dillon,
5
Prawdopodobnie będziesz chciał użyć modułu csv zawartego w standardowej bibliotece, jeśli zamierzasz to zrobić. Na przykład lepiej radzi sobie z cytowaniem.
Flimm
@Flimm jak po prostu pisać do różnych komórek?
oldboy,
jeśli używasz Pythona 3 i plik zawiera znaki spoza zestawu ASCII, na przykład élub , lepiej zrób f.write('\xEF\xBB\xBF')zaraz po open(). To jest BOM ( znak kolejności bajtów , qv), potrzebny oprogramowaniu firmy Microsoft do rozpoznania kodowania UTF-8
Walter Tross,
10
import xlsxwriter


# Create an new Excel file and add a worksheet.
workbook = xlsxwriter.Workbook('demo.xlsx')
worksheet = workbook.add_worksheet()

# Widen the first column to make the text clearer.
worksheet.set_column('A:A', 20)

# Add a bold format to use to highlight cells.
bold = workbook.add_format({'bold': True})

# Write some simple text.
worksheet.write('A1', 'Hello')

# Text with formatting.
worksheet.write('A2', 'World', bold)

# Write some numbers, with row/column notation.
worksheet.write(2, 0, 123)
worksheet.write(3, 0, 123.456)

# Insert an image.
worksheet.insert_image('B5', 'logo.png')

workbook.close()
Naveen Agarwal
źródło
7

Spróbuj też przyjrzeć się następującym bibliotekom:

xlwings - do pobierania danych do i z arkusza kalkulacyjnego z Pythona, a także do manipulowania skoroszytami i wykresami

ExcelPython - dodatek do Excela do pisania funkcji zdefiniowanych przez użytkownika (UDF) i makr w Pythonie zamiast VBA

ehremo
źródło
2

OpenPyxl to całkiem fajna biblioteka, zbudowana do odczytu / zapisu plików Excel 2010 xlsx / xlsm:

https://openpyxl.readthedocs.io/en/stable

Inną odpowiedzią , odnoszącą się do tego, jest użycie zdepercjowanej funkcji ( get_sheet_by_name). Oto jak to zrobić bez niego:

import openpyxl

wbkName = 'New.xlsx'        #The file should be created before running the code.
wbk = openpyxl.load_workbook(wbkName)
wks = wbk['test1']
someValue = 1337
wks.cell(row=10, column=1).value = someValue
wbk.save(wbkName)
wbk.close
Vityata
źródło
1
FileNotFoundError: [Errno 2] No such file or directory: 'New.xlsx'
Powyższy
@Atinesh - Dziękuję za opinię - openpyxl.load_workbookładuje skoroszyt, który jest już obecny. Utwórz plik, New.xlsxaby uniknąć tego błędu.
Vityata
1
OK Dziękuję za sugestię
Atinesh
Zauważ, że openpyxl nie obsługuje starszego formatu „xls”.
Timothy C. Quinn
2

xlsxwriterBiblioteka jest świetna do tworzenia .xlsxplików. Poniższy fragment kodu generuje .xlsxplik z listy dykt podczas określania kolejności i wyświetlanych nazw :

from xlsxwriter import Workbook


def create_xlsx_file(file_path: str, headers: dict, items: list):
    with Workbook(file_path) as workbook:
        worksheet = workbook.add_worksheet()
        worksheet.write_row(row=0, col=0, data=headers.values())
        header_keys = list(headers.keys())
        for index, item in enumerate(items):
            row = map(lambda field_id: item.get(field_id, ''), header_keys)
            worksheet.write_row(row=index + 1, col=0, data=row)


headers = {
    'id': 'User Id',
    'name': 'Full Name',
    'rating': 'Rating',
}

items = [
    {'id': 1, 'name': "Ilir Meta", 'rating': 0.06},
    {'id': 2, 'name': "Abdelmadjid Tebboune", 'rating': 4.0},
    {'id': 3, 'name': "Alexander Lukashenko", 'rating': 3.1},
    {'id': 4, 'name': "Miguel Díaz-Canel", 'rating': 0.32}
]

create_xlsx_file("my-xlsx-file.xlsx", headers, items)

wprowadź opis obrazu tutaj


💡 Uwaga 1 - celowo nie odpowiadam na dokładny przypadek przedstawiony przez PO. Zamiast tego przedstawiam bardziej ogólne rozwiązanie IMHO, którego szuka większość odwiedzających. Tytuł tego pytania jest dobrze indeksowany w wyszukiwarkach i śledzi duży ruch

wprowadź opis obrazu tutaj

💡 Uwaga 2 - Jeśli nie używasz Pythona3.6 lub nowszego, rozważ użycie OrderedDictw headers. Przed Pythonem 3.6 kolejność dictnie była zachowywana.


Jossef Harush
źródło
0

Najłatwiejszym sposobem zaimportowania dokładnych liczb jest dodanie ułamka dziesiętnego po liczbach w l1i l2. Python interpretuje ten przecinek dziesiętny jako instrukcje od Ciebie, aby uwzględnić dokładną liczbę. Jeśli chcesz ograniczyć to do jakiegoś miejsca dziesiętnego, powinieneś być w stanie utworzyć polecenie drukowania, które ogranicza wynik, coś prostego, takiego jak:

print variable_example[:13]

Ograniczy to do dziesiątego miejsca po przecinku, zakładając, że twoje dane mają dwie liczby całkowite na lewo od miejsca dziesiętnego.

Kyle Cyree
źródło
0

Możesz wypróbować hfexcel Human Friendly zorientowaną obiektowo bibliotekę Pythona opartą na XlsxWriter :

from hfexcel import HFExcel

hf_workbook = HFExcel.hf_workbook('example.xlsx', set_default_styles=False)

hf_workbook.add_style(
    "headline", 
    {
       "bold": 1,
        "font_size": 14,
        "font": "Arial",
        "align": "center"
    }
)

sheet1 = hf_workbook.add_sheet("sheet1", name="Example Sheet 1")

column1, _ = sheet1.add_column('headline', name='Column 1', width=2)
column1.add_row(data='Column 1 Row 1')
column1.add_row(data='Column 1 Row 2')

column2, _ = sheet1.add_column(name='Column 2')
column2.add_row(data='Column 2 Row 1')
column2.add_row(data='Column 2 Row 2')


column3, _ = sheet1.add_column(name='Column 3')
column3.add_row(data='Column 3 Row 1')
column3.add_row(data='Column 3 Row 2')

# In order to get a row with coordinates:
# sheet[column_index][row_index] => row
print(sheet1[1][1].data)
assert(sheet1[1][1].data == 'Column 2 Row 2')

hf_workbook.save()
Emin Bugra Saral
źródło
0

Jeśli potrzebujesz zmodyfikować istniejący skoroszyt, najbezpieczniejszym sposobem byłoby użycie pyoo . Musisz mieć zainstalowane biblioteki, a przejście przez nie wymaga kilku obręczy, ale po skonfigurowaniu byłoby to kuloodporne, ponieważ wykorzystujesz szerokie i solidne API LibreOffice / OpenOffice.

Proszę zapoznać się z moim streszczeniem, jak skonfigurować system linux i wykonać podstawowe kodowanie przy użyciu pyoo.

Oto przykład kodu:

#!/usr/local/bin/python3
import pyoo
# Connect to LibreOffice using a named pipe 
# (named in the soffice process startup)
desktop = pyoo.Desktop(pipe='oo_pyuno')
wkbk = desktop.open_spreadsheet("<xls_file_name>")
sheet = wkbk.sheets['Sheet1']
# Write value 'foo' to cell E5 on Sheet1
sheet[4,4].value='foo'
wkbk.save()
wkbk.close()
Timothy C. Quinn
źródło