pip install XlsxWriter★Pure Python, zero dependencies. Import isimport xlsxwriter.import xlsxwriter wb = xlsxwriter.Workbook("out.xlsx") ws = wb.add_worksheet("Sheet1") ws.write("A1", "Hello") wb.close()★The whole lifecycle: Workbook → add_worksheet → write → close. The file is only written onclose().with xlsxwriter.Workbook("out.xlsx") as wb: ws = wb.add_worksheet()★Context manager auto-closes (and thus writes) the file — safer than a manualclose().# forgot wb.close()? -> the .xlsx is empty/corruptgotchaNothing is written untilclose(). Always close (or usewith).
ws.write(0, 0, "text") # (row, col) — 0-indexed ws.write("A1", 42) # or A1 notation★writetakes (row, col) or an "A1" string, and auto-detects the type (number/string/formula/date). Both indexing styles work everywhere.ws.write_row("A1", [1, 2, 3]) ws.write_column("A1", [1, 2, 3])★Write a list across a row or down a column in one call.ws.write_number · write_string · write_boolean · write_datetime · write_url · write_blankType-specific writers when you want to force a type.write_datetimeneeds a date format (card 3) to display correctly.ws.write("A1", value, cell_format)★The optional last arg applies aFormatobject (next card).
bold = wb.add_format({"bold": True, "font_color": "red"}) ws.write("A1", "Hi", bold)★Create a reusableFormaton the workbook and pass it towrite. Props:bold,italic,font_size,font_color,bg_color,align,border.money = wb.add_format({"num_format": "$#,##0.00"}) pct = wb.add_format({"num_format": "0.0%"}) date = wb.add_format({"num_format": "yyyy-mm-dd"})★num_formatuses Excel's format codes — currency, percent, thousands, and dates (dates need a format or they show as serial numbers).fmt = wb.add_format({"align":"center", "valign":"vcenter", "border":1, "bg_color":"#FFEB9C", "text_wrap":True})Alignment, borders, fills, wrapping. Colors are names or#RRGGBB.# create each Format ONCE on the workbook, reuse itgotchaDon't calladd_formatin a loop — make the format objects up front and reuse. A format belongs to its workbook.
ws.set_column("A:A", 20) # width ws.set_column(1, 3, 12, fmt) # cols B:D, width + format★Set column width (in character units) & a default format by range or index.ws.set_row(0, 30, header_fmt) # row height + formatRow height (points) & format.autofit()approximates auto-width for all columns.ws.merge_range("A1:C1", "Title", title_fmt)★Merge cells — the value/format go on the merged range.ws.set_column("D:D", None, None, {"hidden": 1}) ws.set_column("E:E", 15, None, {"level": 1})Hide or group/outline columns (and rows) for collapsible sections.