Skip to content

Eine XLSX-Arbeitsmappe von Grund auf erstellen

XlsxWriter erstellt eine neue Excel-Datei .xlsx im Arbeitsspeicher und schreibt sie auf die Festplatte oder in einen Byte-Buffer — ohne Vorlage, ohne Excel-Installation, ohne COM-Automatisierung. Dies ist das richtige Werkzeug, wenn Sie volle Kontrolle über Tabellenblätter, Zellen, Formatierungen, Zusammenführungen und Spaltenbreiten benötigen, anstatt über das formatunabhängige IR zu arbeiten.

Der Writer ist Teil desselben Rust-Kerns, der XLSX mit durchschnittlich 5,0 ms und 100 % Erfolgsquote bei gültigen Office-Dateien extrahiert, und steht in Python, Rust, Go, C# und JavaScript (natives Node) zur Verfügung.

Wie erstelle ich eine XLSX-Datei von Grund auf?

Erstellen Sie einen XlsxWriter, fügen Sie ein Tabellenblatt hinzu, schreiben Sie Zellen über (row, col) (beide 0-basiert) und rufen Sie dann save auf. Zellwerte können str, int, float, bool oder None sein. Dasselbe Muster funktioniert in allen Bindings.

Rust

use office_oxide::xlsx::write::{XlsxWriter, CellData, CellStyle, NumberFormat};

fn main() -> office_oxide::Result<()> {
    let mut wb = XlsxWriter::new();
    let mut sheet = wb.add_sheet("Sales");

    // Bold header row
    let header = CellStyle::new().bold().background("D3D3D3");
    sheet.set_cell_styled(0, 0, CellData::String("Item".into()),   header.clone());
    sheet.set_cell_styled(0, 1, CellData::String("Amount".into()), header);

    // Data rows
    sheet.set_cell(1, 0, CellData::String("Widget".into()));
    sheet.set_cell(1, 1, CellData::Number(1500.0));
    sheet.set_cell(2, 0, CellData::String("Gadget".into()));
    sheet.set_cell(2, 1, CellData::Number(2400.0));

    // SUM formula with currency formatting (omit the leading '=')
    let currency = CellStyle::new().number_format(NumberFormat::Currency);
    sheet.set_cell_styled(3, 1, CellData::Formula("SUM(B2:B3)".into()), currency);

    // Merge a title banner across two columns
    sheet.merge_cells(4, 0, 1, 2);

    sheet.set_column_width(0, 20.0);
    sheet.set_column_width(1, 15.0);

    wb.save("sales.xlsx")?;
    Ok(())
}

Python

from office_oxide import XlsxWriter

wb = XlsxWriter()
sheet = wb.add_sheet("Sales")          # -> 0 (the sheet index)

# Header row — bold, light-grey fill
wb.set_cell_styled(sheet, 0, 0, "Item",   bold=True, bg_color="D3D3D3")
wb.set_cell_styled(sheet, 0, 1, "Amount", bold=True, bg_color="D3D3D3")

# Data rows: row, col are 0-based
wb.set_cell(sheet, 1, 0, "Widget")
wb.set_cell(sheet, 1, 1, 1500.0)
wb.set_cell(sheet, 2, 0, "Gadget")
wb.set_cell(sheet, 2, 1, 2400.0)

# Widen the columns (Excel character units)
wb.set_column_width(sheet, 0, 20.0)
wb.set_column_width(sheet, 1, 15.0)

wb.save("sales.xlsx")

JavaScript

import { writeFileSync } from 'node:fs';
import { XlsxWriter } from 'office-oxide';

const wb = new XlsxWriter();
const sheet = wb.addSheet('Sales'); // 0-based index

// Header row — bold, grey fill (6-char hex string or null)
wb.setCellStyled(sheet, 0, 0, 'Item', true, 'D3D3D3');
wb.setCellStyled(sheet, 0, 1, 'Amount', true, 'D3D3D3');

// Data rows: value may be null, string, number, or boolean
wb.setCell(sheet, 1, 0, 'Widget');
wb.setCell(sheet, 1, 1, 1500.0);
wb.setCell(sheet, 2, 0, 'Gadget');
wb.setCell(sheet, 2, 1, 2400.0);

wb.mergeCells(sheet, 3, 0, 1, 2);   // title banner: 1 row x 2 cols
wb.setColumnWidth(sheet, 0, 20.0);
wb.setColumnWidth(sheet, 1, 15.0);

wb.save('sales.xlsx');

// Or export to a Buffer:
const data = wb.toBytes();
writeFileSync('sales-copy.xlsx', data);

wb.close(); // release the native handle

Go

package main

import (
	"os"

	officeoxide "github.com/yfedoseev/office_oxide/go"
)

func main() {
	wb := officeoxide.NewXlsxWriter()
	defer wb.Close()

	sheet := wb.AddSheet("Sales") // uint32, 0-based index

	// Header row — bold with a grey fill
	wb.SetCellStyled(sheet, 0, 0, "Item", true, "D3D3D3")
	wb.SetCellStyled(sheet, 0, 1, "Amount", true, "D3D3D3")

	// Data rows: value may be nil, string, float64, int, or bool
	wb.SetCell(sheet, 1, 0, "Widget")
	wb.SetCell(sheet, 1, 1, 1500.0)
	wb.SetCell(sheet, 2, 0, "Gadget")
	wb.SetCell(sheet, 2, 1, 2400.0)

	wb.MergeCells(sheet, 3, 0, 1, 2) // title banner: 1 row x 2 cols
	wb.SetColumnWidth(sheet, 0, 20.0)
	wb.SetColumnWidth(sheet, 1, 15.0)

	if err := wb.Save("sales.xlsx"); err != nil {
		panic(err)
	}

	// Or export to bytes:
	data, err := wb.ToBytes()
	if err != nil {
		panic(err)
	}
	_ = os.WriteFile("sales-copy.xlsx", data, 0o644)
}

C#

using OfficeOxide;

using var wb = new XlsxWriter();
uint sheet = wb.AddSheet("Sales"); // 0-based index

// Header row — bold, grey fill (6-char hex, no '#')
wb.SetCellStyled(sheet, 0, 0, "Item", bold: true, bgColor: "D3D3D3");
wb.SetCellStyled(sheet, 0, 1, "Amount", bold: true, bgColor: "D3D3D3");

// Data rows: value may be null, string, double, int, long, or bool
wb.SetCell(sheet, 1, 0, "Widget");
wb.SetCell(sheet, 1, 1, 1500.0);
wb.SetCell(sheet, 2, 0, "Gadget");
wb.SetCell(sheet, 2, 1, 2400.0);

wb.MergeCells(sheet, 3, 0, 1, 2);   // title banner: 1 row x 2 cols
wb.SetColumnWidth(sheet, 0, 20.0);
wb.SetColumnWidth(sheet, 1, 15.0);

wb.Save("sales.xlsx");

// Or export to a byte[]:
byte[] data = wb.ToBytes();
File.WriteAllBytes("sales-copy.xlsx", data);

C

OfficeXlsxWriterHandle *w = office_xlsx_writer_new();
uint32_t s = office_xlsx_writer_add_sheet(w, "Sales");   /* 0-based index */

/* value_type in the writer: EMPTY=0, STRING=1, NUMBER=2 (no BOOLEAN) */
/* header row — bold + 6-char hex bg ("D3D3D3") or NULL */
office_xlsx_sheet_set_cell_styled(w, s, 0, 0, OFFICE_CELL_STRING, "Item",   0.0, true, "D3D3D3");
office_xlsx_sheet_set_cell_styled(w, s, 0, 1, OFFICE_CELL_STRING, "Amount", 0.0, true, "D3D3D3");

/* data rows */
office_xlsx_sheet_set_cell(w, s, 1, 0, OFFICE_CELL_STRING, "Widget", 0.0);
office_xlsx_sheet_set_cell(w, s, 1, 1, OFFICE_CELL_NUMBER, NULL,     1500.0);
office_xlsx_sheet_set_cell(w, s, 2, 0, OFFICE_CELL_STRING, "Gadget", 0.0);
office_xlsx_sheet_set_cell(w, s, 2, 1, OFFICE_CELL_NUMBER, NULL,     2400.0);

office_xlsx_sheet_merge_cells(w, s, 3, 0, 1, 2);     /* title banner: row_span/col_span >= 1 */
office_xlsx_sheet_set_column_width(w, s, 0, 20.0);   /* Excel char units */
office_xlsx_sheet_set_column_width(w, s, 1, 15.0);

int err = 0;
office_xlsx_writer_save(w, "sales.xlsx", &err);
/* or: uint8_t *b = office_xlsx_writer_to_bytes(w, &out_len, &err); ... office_oxide_free_bytes */
office_xlsx_writer_free(w);

Um die Bytes an eine Web-Antwort oder einen Objektspeicher zu übergeben, anstatt sie auf die Festplatte zu schreiben, verwenden Sie to_bytes() (Python-Beispiel unten):

Python

data = wb.to_bytes()          # -> bytes (a complete .xlsx ZIP)
with open("sales.xlsx", "wb") as f:
    f.write(data)

Methodensignaturen (Python)

Methode Signatur
Erstellen XlsxWriter()
Blatt hinzufügen add_sheet(name: str) -> int
Zelle setzen set_cell(sheet: int, row: int, col: int, value: None|str|bool|int|float) -> None
Formatierte Zelle setzen set_cell_styled(sheet: int, row: int, col: int, value, bold: bool, bg_color: str|None = None) -> None
Zusammenführen merge_cells(sheet: int, row: int, col: int, row_span: int, col_span: int) -> None
Spaltenbreite set_column_width(sheet: int, col: int, width: float) -> None
Speichern save(path) -> None
Exportieren to_bytes() -> bytes

add_sheet gibt den 0-basierten Index des neuen Blatts zurück — übergeben Sie diesen als sheet-Argument an alle weiteren Aufrufe. Zeilen und Spalten sind 0-basiert, sodass Zelle A1 (row=0, col=0) und B1 (row=0, col=1) entspricht.

Wie führe ich Zellen zusammen und erstelle einen Titelbanner?

merge_cells(sheet, row, col, row_span, col_span) führt einen rechteckigen Bereich zusammen, der bei (row, col) verankert ist. Beide Spans müssen >= 1 sein; der Wert der zusammengeführten Zelle stammt aus der Ankerzelle.

Python

from office_oxide import XlsxWriter

wb = XlsxWriter()
s = wb.add_sheet("Report")

# A title that spans columns A through C of the first row
wb.set_cell_styled(s, 0, 0, "Q3 Revenue Report", bold=True, bg_color="FFE699")
wb.merge_cells(s, 0, 0, 1, 3)          # 1 row tall, 3 columns wide

# Sub-header
wb.set_cell_styled(s, 1, 0, "Region", bold=True)
wb.set_cell_styled(s, 1, 1, "Q3",     bold=True)
wb.set_cell_styled(s, 1, 2, "QoQ %",  bold=True)

wb.set_cell(s, 2, 0, "NA")
wb.set_cell(s, 2, 1, 1_200_000)
wb.set_cell(s, 2, 2, 0.18)

wb.set_column_width(s, 0, 18.0)
wb.save("report.xlsx")

Signaturen nach Sprache

Rust — das Rust-Crate bietet einen umfangreicheren Builder. add_sheet gibt einen ausgeliehenen SheetData-Handle zurück, und Zellen nehmen einen CellData-Wert (String, Number, Boolean, Formula oder Empty) sowie ein optionales CellStyle entgegen. CellStyle ist ein Builder, der bold(), italic(), background(), number_format(), align() und mehr unterstützt. Wichtige Signaturen (auf SheetData):

pub fn set_cell(&mut self, row: usize, col: usize, value: CellData) -> &mut Self
pub fn set_cell_styled(&mut self, row: usize, col: usize, value: CellData, style: CellStyle) -> &mut Self
pub fn merge_cells(&mut self, row: usize, col: usize, row_span: usize, col_span: usize) -> &mut Self
pub fn set_column_width(&mut self, col: usize, width: f64) -> &mut Self

sowie auf XlsxWriter: add_sheet(name: &str) -> SheetData<'_>, save(path) -> Result<()> und write_to<W: Write + Seek>(writer) -> Result<()> für In-Memory-Ausgabe. Ein indexbasiertes Spiegelbild (sheet_set_cell, sheet_set_cell_styled, sheet_merge_cells, sheet_set_column_width) steht ebenfalls zur Verfügung, wenn Sie die flache Form der anderen Bindings bevorzugen.

PythonXlsxWriter(), add_sheet(name: str) -> int, set_cell(sheet: int, row: int, col: int, value: None|str|bool|int|float) -> None, set_cell_styled(sheet: int, row: int, col: int, value, bold: bool, bg_color: str|None = None) -> None, merge_cells(sheet: int, row: int, col: int, row_span: int, col_span: int) -> None, set_column_width(sheet: int, col: int, width: float) -> None, save(path) -> None, to_bytes() -> bytes.

JavaScriptaddSheet(name), setCell(sheet, row, col, value), setCellStyled(sheet, row, col, value, bold, bgColor = null), mergeCells(sheet, row, col, rowSpan, colSpan), setColumnWidth(sheet, col, width), save(path), toBytes(), close().

GoNewXlsxWriter() *XlsxWriter, AddSheet(name string) uint32, SetCell(sheet, row, col uint32, value any), SetCellStyled(sheet, row, col uint32, value any, bold bool, bgColor string), MergeCells(sheet, row, col, rowSpan, colSpan uint32), SetColumnWidth(sheet, col uint32, width float64), Save(path string) error, ToBytes() ([]byte, error). Übergeben Sie "" als bgColor für keine Hintergrundfüllung.

C#AddSheet(string name) -> uint, SetCell(uint sheet, uint row, uint col, object? value), SetCellStyled(uint sheet, uint row, uint col, object? value, bool bold, string? bgColor = null), MergeCells(uint sheet, uint row, uint col, uint rowSpan, uint colSpan), SetColumnWidth(uint sheet, uint col, double width), Save(string path), ToBytes() -> byte[]. XlsxWriter implementiert IDisposable.

Coffice_xlsx_writer_new() -> OfficeXlsxWriterHandle*, office_xlsx_writer_add_sheet(w, name) -> uint32_t, office_xlsx_sheet_set_cell(w, sheet, row, col, value_type, value_str, value_num), office_xlsx_sheet_set_cell_styled(w, sheet, row, col, value_type, value_str, value_num, bold, bg_color), office_xlsx_sheet_merge_cells(w, sheet, row, col, row_span, col_span), office_xlsx_sheet_set_column_width(w, sheet, col, width), office_xlsx_writer_save(w, path, &err), office_xlsx_writer_to_bytes(w, &out_len, &err), office_xlsx_writer_free(w). value_type ist OFFICE_CELL_EMPTY (0), OFFICE_CELL_STRING (1) oder OFFICE_CELL_NUMBER (2) — der Writer hat keinen booleschen Zelltyp.

Hinweis: Das XLSX-Schreiben von Grund auf steht in den nativen Bindings (Rust, Python, JavaScript/Node, Go, C#) und der C ABI zur Verfügung. Der Browser-WASM-Build ist schreibgeschützt — er hat keine Writer-Klassen — erstellen Sie Arbeitsmappen daher mit einem der oben genannten Bindings und streamen Sie die Bytes.

Formatierungsreferenz

In den Bindings Python, Go, C#, JavaScript und C bietet der formatierte Setter zwei Optionen:

  • bold — ein boolescher Wert, der der Zelle fettes Schriftgewicht verleiht.
  • bg_color / bgColor — ein 6-stelliger RGB-Hex-String ohne führendes # (z. B. "D3D3D3" für Hellgrau, "FFE699" für Bernstein). Übergeben Sie None / "" / null für keine Hintergrundfüllung.

Der Rust-CellStyle-Builder bietet die vollständige Funktionalität — Kursiv, Unterstreichen, Schriftfarbe, Schriftgröße, Schriftname, Zahlenformate (General, Integer, Decimal2, Currency, Percent, Percent2, Date, DateTime), horizontale Ausrichtung und Textumbruch. Die anderen Bindings stellen die zwei häufigsten Optionen direkt zur Verfügung; für umfangreichere Formatierungen aus diesen Sprachen nutzen Sie das IR oder führen Sie eine Nachbearbeitung durch.

Häufig gestellte Fragen

Sind Zeilen und Spalten 0-basiert oder 1-basiert? Sowohl row als auch col sind 0-basierte Ganzzahlen. Zelle A1 ist (row=0, col=0), B1 ist (row=0, col=1) und A2 ist (row=1, col=0). Der von add_sheet zurückgegebene Blattindex ist ebenfalls 0-basiert.

Muss ich Excel oder ein Microsoft-Runtime installieren? Nein. XlsxWriter erzeugt ein gültiges OOXML .xlsx ZIP vollständig in Rust. Es gibt keine COM-Automatisierung, keine JVM und keine Systemabhängigkeiten — derselbe Motor liest XLSX mit durchschnittlich 5,0 ms und 100 % Erfolgsquote bei gültigen Office-Dateien.

Wie erhalte ich die Datei als Bytes statt auf die Festplatte zu schreiben? Rufen Sie to_bytes() (Python/C#/JS) oder ToBytes() (Go) auf, das einen vollständigen .xlsx-Byte-Buffer zurückgibt. In Rust verwenden Sie write_to(writer) mit einem beliebigen Write + Seek-Ziel wie einem Cursor<Vec<u8>>. Dies ist ideal für HTTP-Antworten und Uploads in Objektspeicher.

Kann ich Formeln schreiben? Ja, in Rust über CellData::Formula("SUM(B2:B3)") (ohne führendes =). Die flachen Bindings (Python/Go/C#/JS) unterstützen derzeit String-, Zahl-, Boolean- und leere Zellwerte über set_cell.

Wie füge ich ein zweites Tabellenblatt hinzu? Rufen Sie add_sheet erneut auf — jeder Aufruf fügt ein Blatt hinzu und gibt den nächsten 0-basierten Index zurück. Übergeben Sie diesen Index als sheet-Argument an die nachfolgenden Aufrufe von set_cell / merge_cells / set_column_width.

Siehe auch