Skip to content

XLSXワークブックをゼロから作成する

XlsxWriterはExcelの.xlsxファイルをメモリ上で新規に構築し、ディスクまたはバイトバッファに書き出します — テンプレート不要、Excelインストール不要、COMオートメーション不要。シート・セル・スタイル・結合・列幅を完全にコントロールしたい場合に最適なツールです。フォーマット非依存IRを経由するアプローチとは異なり、直接XLSXを構築できます。

このライターは、平均5.0ms・有効なOfficeファイルに対して100%のパスレートでXLSXを読み取る同じRustコアの一部であり、Python、Rust、Go、C#、JavaScript(ネイティブNode)から利用できます。

XLSXファイルをゼロから作成するには?

XlsxWriterを構築し、シートを追加し、(row, col)(両方0始まり)でセルを書き込み、saveを呼び出します。セルの値はstrintfloatbool、またはNoneが使えます。同じ形式がすべてのバインディングで動作します。

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);

バイト列をディスクに書き込まずWebレスポンスやオブジェクトストアに渡すには、to_bytes()を使います(以下のPython例を参照)。

Python

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

メソッドシグネチャ(Python)

メソッド シグネチャ
コンストラクト XlsxWriter()
シート追加 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

add_sheetは新しいシートの0始まりのインデックスを返します — これを他のすべての呼び出しのsheet引数として渡します。行と列は0始まりなので、セルA1(row=0, col=0)B1(row=0, col=1)です。

セルを結合してタイトルバナーを作るには?

merge_cells(sheet, row, col, row_span, col_span)(row, col)を起点とした矩形範囲を結合します。両方のスパンは>= 1でなければならず、結合後の値はアンカーセルから取得されます。

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")

言語別シグネチャ

Rust — RustクレートはよりリッチなBuilderを公開しています。add_sheetは借用したSheetDataハンドルを返し、セルはCellData値(StringNumberBooleanFormula、またはEmpty)とオプションのCellStyleを受け取ります。CellStylebold()italic()background()number_format()align()などをサポートするBuilderです。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

XlsxWriterにはadd_sheet(name: &str) -> SheetData<'_>save(path) -> Result<()>、インメモリ出力用のwrite_to<W: Write + Seek>(writer) -> Result<()>があります。他のバインディングと同じフラットな形式を好む場合は、インデックスベースのミラー(sheet_set_cellsheet_set_cell_styledsheet_merge_cellssheet_set_column_width)も利用できます。

PythonXlsxWriter()add_sheet(name: str) -> intset_cell(sheet: int, row: int, col: int, value: None|str|bool|int|float) -> Noneset_cell_styled(sheet: int, row: int, col: int, value, bold: bool, bg_color: str|None = None) -> Nonemerge_cells(sheet: int, row: int, col: int, row_span: int, col_span: int) -> Noneset_column_width(sheet: int, col: int, width: float) -> Nonesave(path) -> Noneto_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() *XlsxWriterAddSheet(name string) uint32SetCell(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) errorToBytes() ([]byte, error)。塗りつぶしなしの場合はbgColor""を渡します。

C#AddSheet(string name) -> uintSetCell(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[]XlsxWriterIDisposableを実装しています。

Coffice_xlsx_writer_new() -> OfficeXlsxWriterHandle*office_xlsx_writer_add_sheet(w, name) -> uint32_toffice_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_typeOFFICE_CELL_EMPTY(0)、OFFICE_CELL_STRING(1)、またはOFFICE_CELL_NUMBER(2)です — ライターにはboolean型のセルはありません。

注意: XLSXのゼロからの書き込みはネイティブバインディング(Rust、Python、JavaScript/Node、Go、C#)とC ABIで提供されています。ブラウザのWASMビルドは読み取り専用です — ライタークラスはありません — そのため、上記のいずれかでワークブックを構築してバイト列をストリーミングしてください。

スタイリングリファレンス

Python、Go、C#、JavaScript、Cバインディングのスタイルセッターはセルにかかわる2つの設定を公開しています:

  • bold — セルにボールドフォントウェイトを適用するboolean値。
  • bg_color / bgColor — 先頭に#なしの6文字RGBhex文字列(例:ライトグレーは"D3D3D3"、アンバーは"FFE699")。塗りつぶしなしにはNone / "" / nullを渡します。

RustのCellStyleBuilderが最も豊富な機能を持ちます — イタリック、下線、フォントカラー、フォントサイズ、フォント名、数値フォーマット(GeneralIntegerDecimal2CurrencyPercentPercent2DateDateTime)、水平方向の配置、テキスト折り返し。他のバインディングは最も一般的な2つのオプションを直接公開しています。これらの言語からより豊富なスタイリングが必要な場合は、IRを経由して構築するか、後処理を行ってください。

よくある質問

行と列は0始まりですか、1始まりですか? rowcolはどちらも0始まりの整数です。セルA1(row=0, col=0)B1(row=0, col=1)A2(row=1, col=0)です。add_sheetが返すシートインデックスも0始まりです。

ExcelやMicrosoftのランタイムをインストールする必要がありますか? いいえ。XlsxWriterは有効なOOXMLの.xlsx ZIPを純粋にRustで生成します。COMオートメーション、JVM、システム依存関係は一切ありません — 同じエンジンが有効なOfficeファイルに対して平均5.0ms・100%のパスレートでXLSXを読み取ります。

ディスクに書き込む代わりにバイト列としてファイルを取得するには? to_bytes()(Python/C#/JS)またはToBytes()(Go)を呼び出すと、完全な.xlsxバイトバッファが返されます。RustではAny Write + Seekターゲット(例:Cursor<Vec<u8>>)を使ってwrite_to(writer)を使用します。これはHTTPレスポンスやオブジェクトストアへのアップロードに最適です。

数式を書き込めますか? はい。RustではCellData::Formula("SUM(B2:B3)")(先頭の=は省略)で使えます。フラットバインディング(Python/Go/C#/JS)では現在set_cellを通じて文字列、数値、boolean、空のセル値を公開しています。

2つ目のワークシートを追加するには? add_sheetを再度呼び出します — 各呼び出しがシートを追加し、次の0始まりインデックスを返します。そのインデックスを後続のset_cell / merge_cells / set_column_width呼び出しのsheet引数として渡します。

関連項目