
JavaScript kann Excel-Arbeitsmappen direkt im Browser generieren. Mit Spire.XLS für JavaScript können Sie eine Arbeitsmappe erstellen, Arbeitsblätter hinzufügen, Werte und Formeln schreiben, Formatierungen anwenden und das Ergebnis entweder als XLSX- oder XLS-Datei speichern – alles clientseitig, ohne dass Microsoft Excel installiert sein muss.
Dieses Tutorial beginnt mit einer einfachen XLSX-Arbeitsmappe und fügt dann typisierte Zellwerte, Formeln, Formatierungen, mehrere Arbeitsblätter, Browser-Download-Unterstützung, CSV-Konvertierung und XLS-Ausgabe für Legacy-Kompatibilität hinzu.
Spire.XLS für JavaScript installieren und initialisieren
Spire.XLS für JavaScript ist im Paket spire.office enthalten, zusammen mit Spire.PDF, Spire.Doc und Spire.Presentation:
npm i spire.office
Das Starten der Runtime erfordert zwei Imports. Der erste startet den gemeinsamen .NET-WebAssembly-Host; der zweite registriert die Tabellenkalkulations-API:
// 1. Boot the shared runtime once per page.
const common = await import('/node_modules/spire.office/spire.common.js');
await common.initializeWasm();
// 2. Load the spreadsheet engine — this is what creates window.spirexls.
await import('/node_modules/spire.office/spire.xls.js');
Die Archive Spire.*.Wasm.zip und der Ordner _framework müssen vom Stammverzeichnis der Website aus erreichbar sein. Die Runtime löst sie anhand der Dokument-URL auf und nicht anhand des Moduls, das den Import durchgeführt hat. In einem Vite- oder Create-React-App-Projekt müssen sie daher in public/ liegen. Das in React-basierten Setups gezeigte Präfix process.env.PUBLIC_URL ist eine Create-React-App-Konvention, kein Browserstandard – passen Sie den Basispfad an Ihr Build-Tool an, wenn Sie nicht CRA verwenden. Wenn die Archive fehlen, protokolliert der Browser WebAssembly.compile(): expected magic word – der Dev-Server hat die Archiv-Anfrage mit index.html beantwortet.
Alles hängt dann von einem einzigen globalen Objekt ab:
const xls = window.spirexls;
Im aktuellen Paket-Setup, das in diesem Tutorial verwendet wird, wird die Tabellenkalkulations-API über window.spirexls bereitgestellt. Verwenden Sie dieses globale Objekt, nachdem die Runtime initialisiert wurde. Ältere Releases haben sie als window.wasmModule.spirexls bereitgestellt; wenn Sie mit einer anderen Paketversion arbeiten, prüfen Sie, welches globale Objekt verfügbar ist.
Sie sind jetzt bereit, Excel-Dateien zu generieren.
Eine einfache Excel-Datei in JavaScript erstellen
Erstellen wir einen Verkaufsbericht. Wir erstellen eine Arbeitsmappe, fügen ein Arbeitsblatt hinzu, schreiben Produktdaten in Zellen und speichern das Ergebnis als XLSX-Datei, die automatisch heruntergeladen wird.
async function createExcelFile() {
const xls = window.spirexls;
if (!xls) {
console.error('Spire.XLS is not initialized.');
return;
}
// A fresh Workbook() already contains three blank worksheets, so clear them
// and add the single sheet this report needs.
const workbook = new xls.Workbook();
workbook.Worksheets.Clear();
const sheet = workbook.Worksheets.Add("Sales Report");
// Sample data: product sales
const data = [
["Product", "Quantity", "Price"],
["Laptop", 10, 999.99],
["Mouse", 50, 24.99],
["Keyboard", 30, 59.99],
["Monitor", 15, 329.99]
];
// Write data to cells
for (let row = 0; row < data.length; row++) {
for (let col = 0; col < data[row].length; col++) {
const cell = sheet.Range.get({ row: row + 1, column: col + 1 });
if (typeof data[row][col] === "string") {
cell.Text = data[row][col];
} else {
cell.NumberValue = data[row][col];
}
}
}
// Save to the virtual file system, read the bytes, download, then dispose
const fileName = "SalesReport.xlsx";
workbook.SaveToFile({
fileName: fileName,
version: xls.ExcelVersion.Version2016
});
const fileData = window.dotnetRuntime.Module.FS.readFile(fileName);
const blob = new Blob([fileData], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
});
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = fileName;
a.click();
URL.revokeObjectURL(url);
workbook.Dispose();
}
Rufen Sie createExcelFile() auf, und Sie erhalten eine SalesReport.xlsx mit vier Produktzeilen plus einer Kopfzeile. Der Workflow ist einfach: Arbeitsmappe erstellen → Daten schreiben → speichern → herunterladen.
Die folgenden Abschnitte erweitern dieses Beispiel. Jedes Code-Snippet geht davon aus, dass es innerhalb von createExcelFile() hinzugefügt wird, nachdem die Arbeitsmappe und das Arbeitsblatt erstellt wurden.

Verschiedene Datentypen in Excel-Zellen schreiben
Excel unterscheidet zwischen Text, Zahlen, Datumsangaben und booleschen Werten. Wenn Sie dies falsch machen, entstehen Dateien, in denen die Sortierung fehlschlägt, Formeln Fehler zurückgeben und Zahlen als Text angezeigt werden.
const sheet = workbook.Worksheets.get(0);
// Text — for labels, names, descriptions
sheet.Range.get("A1").Text = "Product Name";
// Number — for anything you'll calculate, sort, or filter
sheet.Range.get("B1").NumberValue = 999.99;
// Date — a real DateTimeValue plus a display format
const dateCell = sheet.Range.get("C1");
dateCell.DateTimeValue = new Date(Date.UTC(2025, 2, 15));
dateCell.NumberFormat = "yyyy-mm-dd";
// Boolean — use BooleanValue, not text
sheet.Range.get("D1").BooleanValue = true;
Der häufigste Fehler? Sie schreiben cell.Text = "999.99" statt cell.NumberValue = 999.99. Der Wert sieht beim Öffnen der Datei identisch aus, aber Excel behandelt ihn als Text – Sie können ihn nicht summieren, mitteln oder numerisch sortieren. Verwenden Sie immer NumberValue für Zahlen, DateTimeValue für Datumsangaben und BooleanValue für boolesche Werte.
Datumsangaben erfordern eine zusätzliche Vorsichtsmaßnahme. DateTimeValue bewahrt den UTC-Zeitpunkt, der durch das JavaScript-Date dargestellt wird. Das Erstellen eines Datums mit lokaler Mitternacht kann daher in einigen Zeitzonen den angezeigten Tag verschieben; verwenden Sie Date.UTC(), wenn ein bestimmtes Kalenderdatum beibehalten werden soll.
Formeln zum Excel-Arbeitsblatt hinzufügen
Formeln machen Ihre generierte Datei zu einer echten Tabellenkalkulation, nicht nur zu einem Daten-Dump. Fügen wir eine Spalte Total hinzu, die Quantity × Price für jede Zeile berechnet, plus eine Gesamtsumme am Ende:
// Add "Total" header
sheet.Range.get({ row: 1, column: 4 }).Text = "Total";
// Per-row formula: Total = Quantity × Price
for (let i = 2; i <= 5; i++) {
sheet.Range.get({ row: i, column: 4 }).Formula = `=B${i}*C${i}`;
}
// Grand total row
sheet.Range.get({ row: 6, column: 1 }).Text = "Total";
sheet.Range.get({ row: 6, column: 2 }).Formula = "=SUM(B2:B5)";
sheet.Range.get({ row: 6, column: 4 }).Formula = "=SUM(D2:D5)";
// Evaluate the formulas once, so their results are written into the file.
workbook.CalculateAllValue();
Rufen Sie workbook.CalculateAllValue() vor dem Speichern auf, wenn die generierte Arbeitsmappe berechnete Formelergebnisse enthalten soll. Dies ist nützlich für Viewer oder Anwendungen, die auf zwischengespeicherte Werte angewiesen sind, anstatt Formeln beim Öffnen neu zu berechnen.
Eine umfassende Anleitung zu Excel-Funktionen und Formeloperationen finden Sie unter Funktionen und Formeln in Excel-Arbeitsblättern mit JavaScript in React einfügen oder lesen.
Die generierte Excel-Datei formatieren
Eine Tabellenkalkulation mit Rohdaten funktioniert, aber eine formatierte Tabellenkalkulation kommuniziert. Machen wir aus unserem Verkaufsbericht etwas, das Sie tatsächlich an einen Stakeholder senden würden:
// Bold, colored header row
const header = sheet.Range.get("A1:D1");
header.Style.Font.IsBold = true;
header.Style.Font.Size = 12;
header.Style.Color = xls.Color.get_LightSkyBlue();
// Currency format for Price and Total columns
for (let i = 2; i <= 5; i++) {
sheet.Range.get({ row: i, column: 3 }).NumberFormat = "$#,##0.00";
sheet.Range.get({ row: i, column: 4 }).NumberFormat = "$#,##0.00";
}
// Set column widths explicitly
[26, 10, 12, 12].forEach((width, i) => {
sheet.Columns.get(i).ColumnWidth = width;
});
// Clean borders
const usedRange = sheet.Range.get("A1:D6");
usedRange.Borders.LineStyle = xls.LineStyleType.Thin;
usedRange.Borders.Color = xls.Color.get_LightSteelBlue();
Zwei Details sind hier erwähnenswert. sheet.Columns.get(i) und sheet.Rows.get(i) sind 0-basiert und verwenden get, anders als das get_Item, das andere Sammlungen bereitstellen. Und im getesteten Browser-Setup erfordert AutoFitColumn eine Schriftart, die in der WebAssembly-Sandbox nicht verfügbar ist, daher ist das explizite Festlegen von ColumnWidth zuverlässiger.
Das Ergebnis: eine fett gedruckte blaue Kopfzeile, währungsformatierte Preise, richtig dimensionierte Spalten und saubere Rahmen.
Eine ausführliche Anleitung zu Zeilen- und Spaltenabmessungen finden Sie unter Zeilenhöhe und Spaltenbreite in Excel mit JavaScript in React festlegen.
Mehrere Arbeitsblätter in einer Excel-Arbeitsmappe erstellen
Echte Berichte passen selten auf ein Blatt. Ein Verkaufsbericht könnte eine Zusammenfassung auf der ersten Registerkarte, Produktdetails auf der zweiten und monatliche Aufschlüsselungen auf der dritten haben.
workbook.Worksheets.Clear();
const summarySheet = workbook.Worksheets.Add("Summary");
const productsSheet = workbook.Worksheets.Add("Products");
const monthlySheet = workbook.Worksheets.Add("Monthly Data");
// Products sheet — write actual data so cross-sheet formulas work
productsSheet.Range.get("A1").Text = "Product";
productsSheet.Range.get("B1").Text = "Quantity";
productsSheet.Range.get("C1").Text = "Price";
productsSheet.Range.get("D1").Text = "Total";
const products = [
["Laptop", 10, 999.99],
["Mouse", 50, 24.99],
["Keyboard", 30, 59.99],
["Monitor", 15, 329.99]
];
for (let i = 0; i < products.length; i++) {
const row = i + 2;
productsSheet.Range.get({ row: row, column: 1 }).Text = products[i][0];
productsSheet.Range.get({ row: row, column: 2 }).NumberValue = products[i][1];
productsSheet.Range.get({ row: row, column: 3 }).NumberValue = products[i][2];
productsSheet.Range.get({ row: row, column: 4 }).Formula = `=B${row}*C${row}`;
}
// Summary sheet with cross-sheet reference
summarySheet.Range.get("A1").Text = "Sales Summary";
summarySheet.Range.get("A1").Style.Font.IsBold = true;
summarySheet.Range.get("A2").Text = "Total Products";
summarySheet.Range.get("B2").NumberValue = 4;
summarySheet.Range.get("A3").Text = "Total Revenue";
summarySheet.Range.get("B3").Formula = "=SUM(Products!D2:D5)";
Jedes Worksheets.Add(name) gibt das gerade erstellte Blatt zurück, in der Reihenfolge der Aufrufe, sodass die Registerkartenreihenfolge mit der Codereihenfolge übereinstimmt. Beachten Sie die blattübergreifende Formel: =SUM(Products!D2:D5) auf dem Blatt „Summary“ verweist auf die Spalte Total auf dem Blatt „Products“. Excel verarbeitet dies automatisch beim Öffnen der Datei – kein zusätzlicher Code erforderlich.

Weitere Informationen zur Arbeitsblattverwaltung – Hinzufügen, Entfernen und Neuanordnen von Blättern – finden Sie unter Excel-Arbeitsblätter mit JavaScript in React hinzufügen, entfernen und verschieben.
Die XLSX-Datei im Browser speichern und herunterladen
Sobald Ihre Arbeitsmappe fertig ist, speichert Spire.XLS sie in einem virtuellen WebAssembly-Dateisystem. Anschließend lesen Sie die Dateidaten, konvertieren sie in einen Blob und lösen einen Download aus:
workbook.SaveToFile({
fileName: "Report.xlsx",
version: xls.ExcelVersion.Version2016
});
const fileData = window.dotnetRuntime.Module.FS.readFile("Report.xlsx");
const blob = new Blob([fileData], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
});
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "Report.xlsx";
a.click();
URL.revokeObjectURL(url);
workbook.Dispose();
Rufen Sie nach dem Download immer workbook.Dispose() auf, um Speicher freizugeben – insbesondere in Apps, in denen Benutzer mehrere Dateien in einer Sitzung generieren. Die Arbeitsmappe selbst verbleibt bis dahin im WebAssembly-Heap, und dieser Heap wird nicht vom Garbage Collector des Browsers zurückgewonnen.
Suchen Sie React-Integration oder HTML-Tabellenexport? Sehen Sie sich unsere Anleitung zum Herunterladen und Exportieren von Excel-Dateien in JavaScript & React an.
Alles zusammenfügen: Ein formatierter Verkaufsbericht
Die obigen Snippets erstellen eine Arbeitsmappe Stück für Stück. Hier sind sie in einer einzigen Funktion: ein formatiertes Arbeitsblatt mit Zebra-Streifen und Währungsformaten, formelgesteuerten Umsatz- und Anteilsspalten, einem Säulendiagramm und einem zweiten Arbeitsblatt, das die Zahlen zusammenfasst.
/**
* Build a formatted sales report workbook in the browser and download it as
* SalesReport.xlsx.
*
* The layout is driven by `products` below — swap it for form input, an API
* response or component state and nothing else needs to change.
*/
async function createExcelReport() {
// spire.office 11.7.0 exposes Spire.XLS as `window.spirexls`. Older builds
// hung it off `window.wasmModule.spirexls`; that global no longer exists.
const xls = window.spirexls;
if (!xls) throw new Error('Spire.XLS is not ready yet');
// [product, units sold, unit price] — revenue and share are derived by formula
const products = [
['Atlas 14 Ultrabook', 42, 1249.0],
['Orbit Wireless Mouse', 380, 24.99],
['Vertex Mechanical Keyboard', 165, 89.5],
['Lumen 27 4K Monitor', 74, 429.0],
['Halo USB-C Dock', 210, 139.0],
['Pulse ANC Headset', 128, 199.0],
];
const FIRST = 5; // first data row
const TOTAL = FIRST + products.length; // total row
const wb = new xls.Workbook();
wb.Worksheets.Clear();
const sheet = wb.Worksheets.Add('Sales Report');
const at = (a) => sheet.Range.get(a);
const cell = (row, col) => sheet.Range.get({ row: row, column: col });
const paint = (a, colour) => {
at(a).Style.Color = colour;
};
// ── Sizing ── explicit widths (AutoFitColumn is unreliable in the WASM sandbox)
[34, 9, 13, 14, 9].forEach((w, i) => {
sheet.Columns.get(i).ColumnWidth = w;
});
sheet.Rows.get(0).RowHeight = 34; // title
sheet.Rows.get(1).RowHeight = 20; // subtitle
sheet.Rows.get(2).RowHeight = 8; // spacer
sheet.Rows.get(3).RowHeight = 24; // header
// ── Title band ── merge first, then style the whole merged area
at('A1:E1').Merge();
cell(1, 1).Text = 'Sales Report — Q3 2026';
paint('A1:E1', xls.Color.get_DarkBlue());
at('A1:E1').Style.Font.Color = xls.Color.get_White();
at('A1:E1').Style.Font.IsBold = true;
at('A1:E1').Style.Font.Size = 15;
at('A1:E1').Style.VerticalAlignment = xls.VerticalAlignType.Center;
at('A2:E2').Merge();
cell(2, 1).Text = 'Region: West · Period: 1 Jul – 30 Sep 2026 · Amounts in USD';
paint('A2:E2', xls.Color.get_DarkBlue());
at('A2:E2').Style.Font.Color = xls.Color.get_LightSteelBlue();
at('A2:E2').Style.Font.Size = 9.5;
at('A2:E2').Style.VerticalAlignment = xls.VerticalAlignType.Center;
// ── Header row ───────────────────────────────────────────────────────────
['Product', 'Units', 'Unit Price', 'Revenue', 'Share'].forEach((label, i) => {
cell(4, i + 1).Text = label;
});
paint('A4:E4', xls.Color.get_LightSteelBlue());
at('A4:E4').Style.Font.Color = xls.Color.get_DarkBlue();
at('A4:E4').Style.Font.IsBold = true;
at('A4:E4').Style.Font.Size = 10.5;
at('A4:E4').Style.HorizontalAlignment = xls.HorizontalAlignType.Center;
at('A4:E4').Style.VerticalAlignment = xls.VerticalAlignType.Center;
// ── Data rows ── numbers go in as NumberValue, never as text
products.forEach(([name, units, price], i) => {
const r = FIRST + i;
cell(r, 1).Text = name;
cell(r, 2).NumberValue = units;
cell(r, 3).NumberValue = price;
cell(r, 4).Formula = `=B${r}*C${r}`;
cell(r, 5).Formula = `=D${r}/$D${TOTAL}`; // share of the grand total
sheet.Rows.get(r - 1).RowHeight = 20;
if (i % 2) paint(`A${r}:E${r}`, xls.Color.get_WhiteSmoke()); // zebra banding
});
// ── Total row ────────────────────────────────────────────────────────────
cell(TOTAL, 1).Text = 'Total';
[2, 4, 5].forEach((col) => {
const letter = String.fromCharCode(64 + col);
cell(TOTAL, col).Formula = `=SUM(${letter}${FIRST}:${letter}${TOTAL - 1})`;
});
paint(`A${TOTAL}:E${TOTAL}`, xls.Color.get_LightSkyBlue());
at(`A${TOTAL}:E${TOTAL}`).Style.Font.IsBold = true;
sheet.Rows.get(TOTAL - 1).RowHeight = 22;
// ── Number formats and borders ───────────────────────────────────────────
at(`B${FIRST}:B${TOTAL}`).NumberFormat = '#,##0';
at(`C${FIRST}:D${TOTAL}`).NumberFormat = '$#,##0.00';
at(`E${FIRST}:E${TOTAL}`).NumberFormat = '0.0%';
const table = at(`A4:E${TOTAL}`);
table.Borders.LineStyle = xls.LineStyleType.Thin;
table.Borders.Color = xls.Color.get_LightSteelBlue();
at(`A${TOTAL}:E${TOTAL}`).Borders.get_Item(xls.BordersLineType.EdgeTop).LineStyle =
xls.LineStyleType.Medium;
// ── Chart ── build the series by hand (DataRange would mix units)
const chart = sheet.Charts.Add();
chart.ChartType = xls.ExcelChartType.ColumnClustered;
chart.LeftColumn = 6;
chart.TopRow = 3;
chart.RightColumn = 13;
chart.BottomRow = 21;
const serie = chart.Series.Add();
serie.CategoryLabels = at(`A${FIRST}:A${TOTAL - 1}`);
serie.Values = at(`D${FIRST}:D${TOTAL - 1}`);
serie.Name = 'Revenue';
chart.ChartTitleArea.Text = 'Revenue by product';
chart.HasLegend = false;
chart.PrimaryValueAxis.NumberFormat = '$#,##0';
// ── Sheet chrome ──
sheet.FreezePanes(FIRST, 1);
sheet.GridLinesVisible = false;
sheet.TabColor = xls.Color.get_DarkBlue();
// ── Second worksheet: cross-sheet roll-up ──
const summary = wb.Worksheets.Add('Summary');
summary.Columns.get(0).ColumnWidth = 26;
summary.Columns.get(1).ColumnWidth = 18;
summary.Rows.get(0).RowHeight = 30;
summary.Rows.get(1).RowHeight = 18;
summary.Rows.get(3).RowHeight = 22;
const band = (a, text, size) => {
summary.Range.get(a).Merge();
summary.Range.get(a.split(':')[0]).Text = text;
summary.Range.get(a).Style.Color = xls.Color.get_DarkBlue();
summary.Range.get(a).Style.Font.Color = xls.Color.get_White();
summary.Range.get(a).Style.Font.IsBold = true;
summary.Range.get(a).Style.Font.Size = size;
summary.Range.get(a).Style.VerticalAlignment = xls.VerticalAlignType.Center;
};
band('A1:B1', 'Executive Summary', 14);
band('A2:B2', 'Sales Report · Q3 2026', 9.5);
['Metric', 'Value'].forEach((label, i) => {
summary.Range.get({ row: 4, column: i + 1 }).Text = label;
});
summary.Range.get('A4:B4').Style.Color = xls.Color.get_LightSteelBlue();
summary.Range.get('A4:B4').Style.Font.Color = xls.Color.get_DarkBlue();
summary.Range.get('A4:B4').Style.Font.IsBold = true;
[
['Total revenue', "='Sales Report'!D" + TOTAL, '$#,##0.00'],
['Units shipped', "='Sales Report'!B" + TOTAL, '#,##0'],
['Average unit price', `='Sales Report'!D${TOTAL}/'Sales Report'!B${TOTAL}`, '$#,##0.00'],
].forEach(([label, formula, format], i) => {
summary.Range.get({ row: 5 + i, column: 1 }).Text = label;
const value = summary.Range.get({ row: 5 + i, column: 2 });
value.Formula = formula;
value.NumberFormat = format;
value.Style.HorizontalAlignment = xls.HorizontalAlignType.Right;
if (i % 2) summary.Range.get(`A${5 + i}:B${5 + i}`).Style.Color = xls.Color.get_WhiteSmoke();
});
// Date — use Date.UTC to avoid timezone shift
summary.Range.get('A8').Text = 'Report date';
const reportDate = summary.Range.get('B8');
reportDate.DateTimeValue = new Date(Date.UTC(2026, 8, 28));
reportDate.NumberFormat = 'yyyy-mm-dd';
reportDate.Style.HorizontalAlignment = xls.HorizontalAlignType.Right;
const kpis = summary.Range.get('A4:B8');
kpis.Borders.LineStyle = xls.LineStyleType.Thin;
kpis.Borders.Color = xls.Color.get_LightSteelBlue();
summary.GridLinesVisible = false;
summary.TabColor = xls.Color.get_LightSteelBlue();
// ── Save, then release ──
wb.CalculateAllValue();
const fileName = 'SalesReport.xlsx';
wb.SaveToFile({ fileName: fileName, version: xls.ExcelVersion.Version2016 });
const fileData = window.dotnetRuntime.Module.FS.readFile(fileName);
const blob = new Blob([fileData], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});
const url = URL.createObjectURL(blob);
Object.assign(document.createElement('a'), { href: url, download: fileName }).click();
URL.revokeObjectURL(url);
wb.Dispose(); // free the WASM heap — one workbook per generation cycle
}
Das Layout folgt den Daten. Ersetzen Sie das Array products durch eine Antwort Ihrer eigenen API, und alles andere – Summen, Anteilsprozentsätze, der Diagrammbereich, die Zusammenfassung – funktioniert weiterhin, da sie alle als Formeln oder abgeleitete Bereiche und nicht als fest codierte Werte ausgedrückt sind.

Weitere Diagrammtypen und Konfigurationsoptionen finden Sie unter Excel-Diagramme mit JavaScript in React erstellen.
Eine Excel-Datei aus CSV-Daten erstellen
Sie können tabellarische Daten aus einer CSV-Datei in ein Arbeitsblatt laden und das Ergebnis als XLSX speichern. Die resultierende Arbeitsmappe kann dann formatiert oder um Formeln und zusätzliche Arbeitsblätter erweitert werden:
// The library reads from its own virtual file system, so the CSV has to be
// there before you can load it — written from a string here, from the bytes of
// a File object in a real application.
const csv = "Product,Quantity,Price\nLaptop,10,999.99\nMouse,50,24.99\nKeyboard,30,59.99";
window.dotnetRuntime.Module.FS.writeFile("data.csv", new TextEncoder().encode(csv));
workbook.LoadFromFile("data.csv", ",");
workbook.SaveToFile({
fileName: "ConvertedFromCSV.xlsx",
version: xls.ExcelVersion.Version2016
});
Das importierte Blatt wird nach der Datei benannt (data), sodass Worksheets.get(0) es aufgreift.
Das Trennzeichen ist ein erforderliches zweites Argument. LoadFromFile("data.csv") allein wird mit This is not a structured storage file abgelehnt, da die Überladung mit einem Argument ein strukturiertes Format wie .xlsx oder .xls erwartet und CSV nicht erkennt.
Es gibt einen zweiten Haken: Der CSV-Importer schreibt jedes Feld als Text. Eine Mengenspalte kommt als "10" statt als 10 an, was bedeutet, dass sie nicht numerisch summiert oder sortiert werden kann – genau das Problem, das zuvor in diesem Tutorial beschrieben wurde. Konvertieren Sie die benötigten Spalten vor dem Speichern:
const csvSheet = workbook.Worksheets.get(0);
// The importer leaves every field as text — coerce each numeric column.
// Columns 2 and 3 hold Quantity and Price; both arrive as "10" and "999.99".
for (let row = 2; row <= 4; row++) {
[2, 3].forEach((column) => {
const cell = csvSheet.Range.get({ row: row, column: column });
if (cell.Text !== "") {
cell.NumberValue = Number(cell.Text);
}
});
}
Eine vollständige Anleitung zur Konvertierung zwischen CSV- und Excel-Formaten finden Sie in unserem Tutorial zur CSV-zu-Excel-Konvertierung.
Eine XLS-Datei statt XLSX erstellen
Wenn Ihre Anwendung das Legacy-Format .xls statt .xlsx generieren muss, ändern Sie den Versionsparameter:
workbook.SaveToFile({
fileName: "Report.xls",
version: xls.ExcelVersion.Version97to2003
});
Das Enum-Element ist Version97to2003 – es gibt kein Version97. Behalten Sie Diagramme in XLSX; der getestete XLS-Writer schlägt fehl, wenn Diagramm-Schriftartmetriken erforderlich sind.
XLSX (Excel 2007+) ist das empfohlene Format für neue Anwendungen. XLS (Excel 97–2003) ist nur erforderlich, wenn Abwärtskompatibilität benötigt wird.
Häufige Probleme
window.wasmModule ist nicht definiert. Ältere Beispiele lesen die Tabellenkalkulations-API aus window.wasmModule.spirexls. Aktuelle Releases installieren sie direkt auf window.spirexls und lassen wasmModule nicht definiert, sodass bereits der erste Zugriff einen Fehler auslöst. Prüfen Sie stattdessen window.spirexls.
WASM-Modul nicht initialisiert. Wenn window.spirexls nicht definiert ist, hat die Runtime das Laden noch nicht abgeschlossen. Zeigen Sie einen Ladeindikator an und warten Sie, bis die Initialisierung abgeschlossen ist, bevor Sie Excel-Operationen versuchen.
Auto-Fit löst einen Schriftartfehler aus. AutoFitColumn und AutoFitRow benötigen eine Systemschriftart zum Messen von Text, und die WebAssembly-Sandbox hat keine. Sie schlagen mit Cannot found font(Arial) installed on the system. fehl. Berechnen oder hardcoden Sie Ihre Spaltenbreiten mit sheet.Columns.get(i).ColumnWidth.
Zahlen als Text gespeichert. Die Verwendung von cell.Text = "100" statt cell.NumberValue = 100 bricht Sortierung und Berechnungen. Dies ist das häufigste Problem, auf das Entwickler beim Schreiben von Excel-Dateien in JavaScript stoßen, und der CSV-Import löst es automatisch aus – verwenden Sie immer NumberValue für numerische Daten.
Ein Blatt "Evaluation Warning" erscheint. Wenn Sie die Evaluierungsversion ohne gültige Lizenz verwenden, fügt Spire.XLS der gespeicherten Arbeitsmappe ein Evaluierungsblatt hinzu. Dieses Blatt wird beim Speichern neu erstellt, sodass das programmgesteuerte Entfernen kein zuverlässiger Workaround ist. Wenden Sie einen Lizenzschlüssel an, um dies zu verhindern.
Speicherlecks in lang laufenden Apps. Rufen Sie workbook.Dispose() nach jedem Generierungszyklus auf. In Single-Page-Anwendungen sammeln nicht freigegebene Arbeitsmappen Speicher an und beeinträchtigen die Leistung im Laufe der Zeit.
FAQ
Kann JavaScript Excel-Dateien ohne Microsoft Excel erstellen?
Ja. Spire.XLS für JavaScript läuft vollständig im Browser über WebAssembly. Es ist keine Installation von Microsoft Excel oder server-seitigem Office erforderlich, um XLSX-Dateien zu generieren.
Kann JavaScript XLSX-Dateien direkt im Browser erstellen?
Ja. Alle Tabellenkalkulationsoperationen erfolgen clientseitig. Die Datei wird in einem virtuellen Dateisystem gespeichert und dann als Blob heruntergeladen – kein Backend-Server erforderlich.
Was ist der Unterschied zwischen XLS und XLSX?
XLSX (Excel 2007 und später) ist das moderne XML-basierte Format, empfohlen für neue Anwendungen. XLS (Excel 97–2003) ist das ältere binäre Format, nützlich für die Kompatibilität mit älteren Systemen.
Fazit
Das Erstellen von Excel-Dateien in JavaScript erfordert keinen Backend-Server oder Microsoft Excel. Mit Spire.XLS für JavaScript können Sie Arbeitsmappen von Grund auf erstellen, typisierte Daten schreiben, Formeln hinzufügen, Formatierungen anwenden und Daten über mehrere Blätter organisieren – alles im Browser.
Beginnen Sie mit dem obigen einfachen Beispiel und ergänzen Sie dann Formeln und Formatierungen, wenn Ihre Anforderungen wachsen. Für React-spezifische Integration und HTML-Tabellenexport lesen Sie unser dediziertes Export-Tutorial.