コンバータ:最もシンプルな1行、どんな環境でも最も柔軟に

Aspose.Cells for Go via C++ Toolkits の converter パッケージは、スプレッドシートを別の形式に変換するというすべてのニーズを 1 つのエントリ関数 に削減します:

converter.Convert(source, saveOption, sink) error

それは3つのパラメーターだけで構成されており、各パラメーターは正確に1つの質問に答えます。

パラメータ型何を問うか典型的な値
sourcedatasource.DataSource入力はどこから来ますか?FilePathSource(path), BytesSource(data), NewReaderSource(r)
saveOptionsaveoptions.SaveOption出力は何形式で、どのように調整しますか?formats.Get("pdf") for defaults by name, or pdf.New(pdf.WithOnePagePerSheet(true)) for fine control
sinkdatasource.DataSink出力はどこへ行きますか?FilePathSink(path), &BytesSink{}, NewWriterSink(w)

最も簡潔 スタイルの場合は、3 つの軸すべてでデフォルトを使用します。最も柔軟 スタイルの場合は、各ノブを個別に設定します。3 つの軸が独立しているため、同じ Convert がファイル、メモリ、HTTP、バッチ環境に自然に適合します。(プレーンな file→file ケース用のレガシーなワンライナー ConvertSpreadsheetToFile もあり、下記セクション 1 で比較しています。)この記事の残りの部分は、最も簡潔なものから最も柔軟なものへと移行し、別の API に切り替えるのではなく、前のスニペットをステップごとに拡張していきます。

1. 最もシンプルな方法: 1つのフォーマットにつき1回の呼び出し

1.1 組み込みの file→file ワンライナー: ConvertSpreadsheetToFile

このパッケージには、古い、さらに短いエントリも同梱されており、古典的な「convert this file into that file」ケースに対応しています。必要なのは2つのパスだけです。

package main

import (
	"log"
	"github.com/aspose-cells/aspose-cells-go-cpp-toolkits/v26/core"
	"github.com/aspose-cells/aspose-cells-go-cpp-toolkits/v26/converter"
	_ "github.com/aspose-cells/aspose-cells-go-cpp-toolkits/v26/register" // registers every output format
)

func main() {
	defer core.Cleanup()
	// Both ends are files; the output format is inferred from the extension.
	if err := converter.ConvertSpreadsheetToFile("input.xlsx", "output.pdf"); err != nil {
		log.Fatal(err)
	}
}

非推奨 ConvertSpreadsheetToFile は下位互換性を保つために残された薄いラッパーです; 新しいコードは以下の converter.Convert に向けられます。ファイル→ファイルの場合、両者は完全に同等です — これが ConvertSpreadsheetToFile のすべての動作です:

opt := formats.Get(strings.TrimPrefix(filepath.Ext("output.pdf"), ".")) // "pdf"
converter.Convert(
	datasource.FilePathSource("input.xlsx"), // input: a file
	opt,                                     // format: taken from the extension
	datasource.FilePathSink("output.pdf"),   // output: a file
)

ConvertSpreadsheetToFile と上記の Convert 形式は同じ結果を生成します。違うのはシナリオで、次に比較します。

1.2 推奨のワンライナー: デフォルトで Convert

package main

import (
	"log"
	"github.com/aspose-cells/aspose-cells-go-cpp-toolkits/v26/core"
	"github.com/aspose-cells/aspose-cells-go-cpp-toolkits/v26/converter"
	"github.com/aspose-cells/aspose-cells-go-cpp-toolkits/v26/datasource"
	"github.com/aspose-cells/aspose-cells-go-cpp-toolkits/v26/saveoptions/pdf"
)

func main() {
	defer core.Cleanup()
	if err := converter.Convert(
		datasource.FilePathSource("input.xlsx"), // input: a file
		pdf.New(),                               // format: PDF, all defaults
		datasource.FilePathSink("output.pdf"),   // output: a file
	); err != nil {
		log.Fatal(err)
	}
}

すべての3つの設定はデフォルトを使用します: 入力 = ファイル、フォーマット = pdf.New()(設定なし)、出力 = ファイル。これが「most concise」な形 — 手動での os.Open/os.Create は不要で、オブジェクト割り当てもハンドルのクローズも不要です。ソース/シンクがリソースを管理します。

1.3 2つの file→file 形状の比較

ConvertSpreadsheetToFile(in, out)converter.Convert(source, opt, sink)
Inputファイルパスのみ任意の DataSource: パス、[]byte、またはリーダー
Outputファイルパスのみ任意の DataSink: パス、バイト、または io.Writer
Output format常に拡張子から推測され、デフォルトのみ任意の saveOption: デフォルトまたはフォーマット固有の調整
Extra importフォーマットを登録する必要があります (_ \"…/register\"、または一致する saveoptions/* サブパッケージ)なし、pdf.New() のようなコンストラクタを渡す場合
Status非推奨の薄いラッパー(安定版、互換性のために保持)新しいコード向けに文書化された単一エントリーポイント

同じファイル→ファイルの結果、2つの異なるシナリオ:

  • ConvertSpreadsheetToFile — 文字通り2つのパスしかなく、ターゲット形式のエンジン既定設定で問題ありません。ワンオフの変換スクリプト、マイグレーションバッチ、テストヘルパーに最適です。その代償は: 入力、出力、設定が「file path + defaults」の形から離れないことです — そして非推奨です。
  • converter.Convert — 同じワンライナーが欲しいが、3つの引数のいずれかは置き換え可能です: 将来、入力がアップロードされた []byte になる、ターゲットに pdf.WithOnePagePerSheet(true) が必要になる、または出力を直接 HTTP 応答に送る必要がある、というシナリオです。これらはセクション 3 と 4 のシナリオそのものです — Convert で一度書けば、変更はすべて1つの引数の編集になります。

2. 最もシンプルな × N: すべての 32 フォーマットに対する単一関数

次のレベルの簡潔さは、対象とするフォーマットに関係なく 同じ関数 を使用することです。saveOption は出力ファイルの拡張子から計算できるため、その推論を取り出すと「ユニバーサル ファイル コンバータ」になります。

package main

import (
	"errors"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"
	"github.com/aspose-cells/aspose-cells-go-cpp-toolkits/v26/core"
	"github.com/aspose-cells/aspose-cells-go-cpp-toolkits/v26/converter"
	"github.com/aspose-cells/aspose-cells-go-cpp-toolkits/v26/datasource"
	toolkiterrors "github.com/aspose-cells/aspose-cells-go-cpp-toolkits/v26/errors"
	"github.com/aspose-cells/aspose-cells-go-cpp-toolkits/v26/formats"
	_ "github.com/aspose-cells/aspose-cells-go-cpp-toolkits/v26/register" // registers every output format
)

// convert re-saves in as out; the output format is read from out's extension.
// The same code handles every built-in format (pdf/csv/html/md/xlsx/png/…).
// It is exactly what the deprecated ConvertSpreadsheetToFile does internally.
func convert(in, out string) error {
	opt := formats.Get(strings.TrimPrefix(filepath.Ext(out), ".")) // ".pdf" -> "pdf"
	if opt == nil {
		return fmt.Errorf("%w: %q", toolkiterrors.ErrUnsupportedFormat, filepath.Ext(out))
	}
	return converter.Convert(
		datasource.FilePathSource(in), // where the input comes from
		opt,                           // what to produce: decided by the extension
		datasource.FilePathSink(out),  // where the output goes
	)
}

func main() {
	defer core.Cleanup()
	if len(os.Args) != 3 {
		log.Fatalf("usage: %s <input.xlsx> <output.ext>", os.Args[0])
	}
	if err := convert(os.Args[1], os.Args[2]); err != nil {
		if errors.Is(err, toolkiterrors.ErrUnsupportedFormat) {
			log.Printf("no registered output format for %q", filepath.Ext(os.Args[2]))
		}
		log.Fatal(err)
	}
	fmt.Println("done")
}

使用方法は同じままです — 出力拡張子だけが変更されます:

$ go run . input.xlsx report.pdf     # to PDF
$ go run . input.xlsx report.csv     # to CSV
$ go run . input.xlsx report.html    # to HTML
$ go run . input.xlsx notes.md       # to Markdown
$ go run . input.xlsx sheet.png      # to a PNG image
$ go run . input.xlsx legacy.xls     # to legacy Excel

その空白の _ "…/register" インポートは何ですか?

saveOption を取得する方法は 2 つあります。これは “most concise” スタイルが理解する必要がある唯一の概念です:

  • フォーマット名でレジストリから取得する (formats.Get): 拡張子は formats レジストリに存在している必要があります。各 saveoptions/* サブパッケージはそれぞれの init() で自身を登録しますが、インポートされたときだけです。必要なサブパッケージを一つずつインポートします(PDF に変換する場合は pdf だけなど)、または 空インポート …/register を一度行う と、すべての 32 フォーマットが一括で登録されます — 上記の「ユニバーサルコンバータ」はこの一行に依存しています。
  • コンストラクタを直接呼び出す (pdf.New(), markdown.New()): レジストリをバイパスし、register のインポートは不要です。使用するフォーマットごとにインポート行が 1 行必要になるというコストがあります。

要約すると、formats.Get と出力拡張子で解決する場合にのみ _ "…/register" を使用します。コンストラクタを直接渡す場合は特に何も必要ありません。空インポートは無害で、公式サンプルでは常に存在しています。

3. 最も柔軟: 各ノブを個別に調整

必要が「デフォルト設定のファイルからファイルへの変換」以上になる場合、API を変更する必要はありません — 3 つの Convert パラメータはそれぞれ独立して入れ替え可能です。

1. 入力(ソース):ファイルから、メモリへ、任意のストリームへ

datasource.FilePathSource("input.xlsx") // a file on disk
datasource.BytesSource(data)            // []byte already in memory (downloads, cached reuse)
datasource.NewReaderSource(r.Body)      // any io.Reader (HTTP body, compressed stream, …)

注意: 基礎となるエンジンはコンテンツ全体へのランダムアクセスが必要なため、ReaderSource は最初のアクセス時にストリーム全体をバッファに保持します。その後のすべての Open はそのバッファのコピーを提供します。HTTP で自信を持って使用できますが、実際の「ストリーミング中に変換」ではないことを理解してください。

2. フォーマット (saveOption): デフォルト、または調整

ScenarioWriting styleWhy
デフォルト設定のフォーマットformats.Get("pdf")拡張子で検索され、大小文字を区別せず、未登録の場合は nil
フォーマット固有のオプションがあるフォーマットpdf.New(pdf.WithOnePagePerSheet(true))関数オプション
デフォルト設定、明示的なフォーマットooxml.New() / csv.New() / …フォーマットごとに引数なしのコンストラクタが1つ
カスタムプライベートフォーマットformats.Register("fmt", factory)レジストリにプラグインする — 参照 docs/register.md

機能オプションは、それらを持つフォーマットでのみ表示されます: PDF でシートごとに 1 ページにするオプションは WithOnePagePerSheet、HTML で画像をインラインにするオプションは WithExportImagesAsBase64、TSV は formats.Get("tsv") です。オプションはポインタ セマンティクスです: 省略するとエンジンのデフォルトが使用され、false を明示的に渡すことも同様にカウントされます。

3. 出力 (シンク): ファイル、バイト、または io.Writer

datasource.FilePathSink("output.pdf") // to disk (parent dirs are created)
&out                                 // into memory; read it back with out.Bytes()
datasource.NewWriterSink(w)          // straight into any io.Writer (http.ResponseWriter, buffer, socket)

BytesSink と WriterSink は「most flexible」の2つの鍵です: これらは変換結果をディスクに書き込まず、HTTPレスポンス、オブジェクトストレージ、ZIP などに直接流すことができます。すべては同じ sink パラメータの異なる実装であり、[]byte または io.Writer を受け取るものはすべてコンバータに組み込むことができます。


4. 実環境の例: 1つの Convert、多数のシェイプ

A. メモリ内で変換; ダウンロードエンドポイントは PDF をストリームします

一般的なサーバーサイドのシナリオ — ユーザーが xlsx をアップロードし、エンドポイントが PDF を返し、テンポラリファイルは作成されません。

func handleExcelToPDF(w http.ResponseWriter, r *http.Request) {
	var out datasource.BytesSink
	if err := converter.Convert(
		datasource.NewReaderSource(r.Body),    // input: the request body
		pdf.New(pdf.WithOnePagePerSheet(true)), // format: PDF, one page per sheet
		&out,                                   // output: memory
	); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	w.Header().Set("Content-Type", "application/pdf")
	w.Header().Set("Content-Disposition", `attachment; filename="report.pdf"`)
	_, _ = w.Write(out.Bytes())
}

CSV / Excel / HTML を配布する場合は、saveOption だけを入れ替えてください(例: formats.Get("csv"))。他に変更する必要はありません。

B. 一度読み取り、複数の形式へバッチエクスポート

入力を一度だけ読み取り、BytesSource を通じて任意の数の出力に再利用します — 「export every report」に最適です。

data, err := os.ReadFile("input.xlsx")
if err != nil {
	log.Fatal(err)
}

for _, ext := range []string{"pdf", "csv", "html", "json", "md"} {
	var out datasource.BytesSink
	if err := converter.Convert(datasource.BytesSource(data), formats.Get(ext), &out); err != nil {
		log.Fatalf("%s: %v", ext, err)
	}
	if err := os.WriteFile("output."+ext, out.Bytes(), 0o644); err != nil {
		log.Fatal(err)
	}
}

C. スプレッドシート ファミリー内の「Save as」(移行 / 互換性)

スプレッドシート ファミリー内でのフォーマット変換、例: xlsx → xls, xlsx → xlsb, xlsx → ods、およびテンプレート xltx/xltm — 依然として 1 つの Convert で、変更されるのは saveOption だけです:

src := datasource.FilePathSource("input.xlsx")
converter.Convert(src, formats.Get("xls"),  datasource.FilePathSink("legacy.xls")) // legacy Excel
converter.Convert(src, formats.Get("xlsb"), datasource.FilePathSink("binary.xlsb")) // binary Excel
converter.Convert(src, formats.Get("ods"),  datasource.FilePathSink("open.ods"))    // OpenDocument
converter.Convert(src, formats.Get("xltx"), datasource.FilePathSink("template.xltx")) // template

D. 必要な場合にのみ、フォーマットごとにオプションを調整する

機能オプションは、細かい制御が必要なときに現れます — 以下のすべての呼び出しは実際のもので、正しく型付けされています:

// PDF: one page per worksheet + a compliance level
pdf.New(
	pdf.WithOnePagePerSheet(true),
	pdf.WithCompliance("pdf15"),
	pdf.WithProducer("my-report-app"),
)

// HTML: single file, images inlined as base64, CSS prefix (avoids style clashes)
html.New(
	html.WithSaveAsSingleFile(true),
	html.WithExportImagesAsBase64(true),
	html.WithCellCssPrefix("tbl_"),
)

// CSV: custom separator and encoding
// (the separator is a byte, and the encoding is a name — matched case- and
// punctuation-insensitively, so "UTF-8", "utf8" and "UTF8" are one name)
csv.New(
	csv.WithSeparator(';'),
	csv.WithEncoding("UTF-8"),
)

// Image: pick the type (the only switch the image package currently exposes)
image.New(image.WithImageType("png")) // or "jpg" / "svg" / "gif" / "tif" / …

Tip: CSV/HTML/画像 などの単一ファイル出力の場合、エンジンはデフォルトで「アクティブ」なワークシートのみをエクスポートします。範囲を制御するには、各フォーマット固有のオプションを使用してください — 例: html.WithExportActiveWorksheetOnly(true)(アクティブシートのみ?)、html.WithShowAllSheets(true)、または csv.WithExportAllSheets(true)。ピクセル単位の画像品質や、正確にどのシートをレンダリングするかの選択、その他の詳細な制御はエンジン層にまだ存在しますが、現在の image パッケージでは WithImageType スイッチだけが公開されています。さらに必要な場合は基盤のバインディングを利用してください。ツールキットは今後もオプションを追加していく予定です。

E. ディレクトリ全体のバッチ変換

日常的な「このフォルダーのExcelをPDFに変換する」作業は、拡張子推論を使用すると非常に短くなります:

func convertAll(inputDir, outputDir string) error {
	if err := os.MkdirAll(outputDir, 0o755); err != nil {
		return err
	}
	return filepath.Walk(inputDir, func(path string, info os.FileInfo, err error) error {
		if err != nil || info.IsDir() {
			return err
		}
		ext := strings.ToLower(filepath.Ext(path))
		if ext != ".xlsx" && ext != ".xls" && ext != ".xlsm" && ext != ".csv" {
			return nil
		}
		out := filepath.Join(outputDir, strings.TrimSuffix(filepath.Base(path), ext)+".pdf")
		if err := convert(path, out); err != nil { // reuse the convert from section 2
			return fmt.Errorf("convert %s: %w", path, err)
		}
		fmt.Printf("done: %s -> %s\n", path, out)
		return nil
	})
}

F. エラーの分類

コンバータ エラーは分類可能なセンチネル エラーです; 正確な処理のために errors.Is と組み合わせてください:

err := convert("in.xlsx", "out.xyz")
switch {
case errors.Is(err, toolkiterrors.ErrUnsupportedFormat):
	log.Println("this extension has no registered output format")
case errors.Is(err, os.ErrNotExist):
	log.Println("the input file does not exist")
default:
	log.Printf("conversion failed: %v", err)
}

formats.List() は現在登録されているすべての拡張子を返します(ソート済み、同時実行安全)— 「サポートされているフォーマット」リストやエラーヒントの生成に便利です。


5. 一目でわかるサポート形式(デフォルトで登録されている32種)

ファミリー出力拡張子チューニング パッケージ
Excelxlsx xlsm xltx xltm xls xlsbsaveoptions/ooxml, xls, xlsb
OpenDocumentods xml dif dbfsaveoptions/ods, xml, dif, dbf
テキスト / データcsv txt tsv json sqlsaveoptions/csv, txt, json, sqlScript
ドキュメント / レイアウトpdf docx pptx xps pcl epubsaveoptions/pdf, docx, pptx, xps, pcl, ebook
Webhtml mdsaveoptions/html, markdown
画像png jpg jpeg gif bmp svg emf tif tiffsaveoptions/image

バイナリを軽量に保つため、使用するサブパッケージだけをインポートします(例: pdf)。利便性や汎用ディスパッチのために、空インポート …/register を使用できます。サブパッケージをインポートするとその登録が行われます。レジストリの検索は大文字小文字を区別しません。未登録の拡張子は nil を返します(エラーではなく)、フォールバックの判断は呼び出し側に委ねられます。


6. ベストプラクティスと注意点

  1. エントリーポイントは1つだけ — 再実装しないでください。 File-to-file は Convert(FilePathSource, formats.Get(ext)/constructor, FilePathSink) を使用します; バイトやストリームが必要なときだけシンクを切り替えてください。 os.Open → ReadAll → … → os.WriteFile を自前で書かないでください; ソース/シンクがリソースを管理し、親ディレクトリも作成してくれます。
  2. 同時実行とライセンス。 基盤エンジンはネイティブです: 同一プロセス内の複数 goroutine で SaveOption/workbook オブジェクトを共有しないでください; バルク処理はファイルを順次処理するか、プロセス間で並列化してください。評価ビルドはロード回数に上限があります(プロセスあたり約100回の NewWorkbook_Stream ロード)— 大規模ベンチマークではカウンタをリセットするためにプロセスを再起動してください。
  3. 入力は一度だけ読み取り、再利用してください。 1つの入力から複数のフォーマットを出力するには、まず os.ReadFile で []byte に読み込み、BytesSource で繰り返し変換します。これによりディスク読み取りや再ロードを繰り返すことを防げます。
  4. ストリームはバッファリングされます。 NewReaderSource は最初のアクセス時にバッファリングするため、HTTP リクエストボディのようなワンショット入力に適していますが、非常に大きなファイルの真のストリーミングには向きません(その場合はディスク直下を指す FilePathSource を使用してください)。
  5. 出力レイアウトの決定者を把握してください。 Convert は「1入力 → 1出力ファイル」です。シートごとに1ファイルやZIPが必要な場合は、manipulator.Split と FolderSink/ZipSink を使用します — Convert で無理に行わないでください。