Převodník: jeden řádek v jeho nejjednodušší podobě, jakékoli prostředí v jeho nejflexibilnější podobě
Balíček converter z Aspose.Cells for Go via C++ Toolkits snižuje každou potřebu „převést tabulku do jiného formátu“ na jednu vstupní funkci:
converter.Convert(source, saveOption, sink) error
Má jen tři parametry a každý odpovídá přesně na jednu otázku:
| Parametr | Typ | Otázka, na kterou odpovídá | Typické hodnoty |
|---|---|---|---|
source | datasource.DataSource | Odkud vstup pochází? | FilePathSource(path), BytesSource(data), NewReaderSource(r) |
saveOption | saveoptions.SaveOption | Jaký je výstup a jak je nastaven? | formats.Get("pdf") pro výchozí hodnoty podle názvu, nebo pdf.New(pdf.WithOnePagePerSheet(true)) pro jemné nastavení |
sink | datasource.DataSink | Kam výstup směřuje? | FilePathSink(path), &BytesSink{}, NewWriterSink(w) |
Pro nejstručnější styl použijte výchozí nastavení na všech třech osách; pro nejflexibilnější otočte každý ovladač nezávisle. Protože jsou tři osy nezávislé, stejná Convert přirozeně vyhovuje souborovým, paměťovým, HTTP a dávkovým prostředím. (Existuje také starší jednorázová metoda ConvertSpreadsheetToFile pro jednoduchý případ soubor→soubor — porovnáno v sekci 1 níže.) Zbytek tohoto článku přechází od nejstručnějšího k nejflexibilnějšímu, přičemž postupně rozšiřuje předchozí úryvek místo přepnutí na jiné API.
1. Nejjednodušší: jedno volání pro jeden formát
1.1 Vestavěný file→file jednorázový příkaz: ConvertSpreadsheetToFile
Balíček také obsahuje starší, ještě kratší vstup pro klasický případ „převést tento soubor na ten soubor“. Stačí jen dvě cesty:
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)
}
}
Zastaralé.
ConvertSpreadsheetToFileje tenký obal zachovaný pro zpětnou kompatibilitu; nový kód je nasměrován naconverter.Convertníže. Pro případ soubor→soubor jsou oba přesně ekvivalentní — to je vše, coConvertSpreadsheetToFiledělá:
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 a výše uvedená forma Convert produkují identické výsledky; liší se scénář, jak je uvedeno níže.
1.2 Doporučený jednorázový příkaz: Convert s výchozími hodnotami
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)
}
}
Všechny tři ovládací prvky používají výchozí hodnoty: input = soubor, format = pdf.New() s nulovou konfigurací, output = soubor. To je “nejstručnější” podoba — žádné ruční os.Open/os.Create, žádná alokace objektů, žádné uzavírání handle; source/sink spravují prostředky za vás.
1.3 Porovnání dvou tvarů soubor→soubor
ConvertSpreadsheetToFile(in, out) | converter.Convert(source, opt, sink) | |
|---|---|---|
| Vstup | pouze cesta k souboru | libovolný DataSource: cesta, []byte, nebo čtečka |
| Výstup | pouze cesta k souboru | libovolný DataSink: cesta, bajty, nebo io.Writer |
| Formát výstupu | vždy odvozeno z přípony, pouze výchozí hodnoty | libovolná saveOption: výchozí nebo ladění specifické pro formát |
| Další import | vyžaduje registraci formátu (_ \"…/register\", nebo odpovídající podbalíček saveoptions/*) | žádný, pokud předáte konstruktor jako pdf.New() |
| Stav | zastaralý tenký obal (stabilní, zachován pro kompatibilitu) | dokumentovaný jediný vstupní bod pro nový kód |
Stejný soubor → výsledek souboru, dva různé scénáře:
ConvertSpreadsheetToFile— doslova máte dvě cesty a jste spokojeni s výchozími nastaveními enginu pro cílový formát. Ideální pro jednorázové konverzní skripty, migrační dávky a testovací pomocníky. Jeho cena: vstup, výstup a nastavení nikdy nemohou opustit tvar „file path + defaults“ — a je zastaralý.converter.Convert— chcete stejný jednorázový řádek, ale kterýkoliv ze tří argumentů zůstane zaměnitelný: zítra bude vstup[]bytenahraný, cíl bude potřebovatpdf.WithOnePagePerSheet(true), nebo výstup by měl jít přímo do HTTP odpovědi. To jsou přesně scénáře sekcí 3 a 4 — napište to jednou pomocíConverta každá změna bude úprava jednoho argumentu.
2. Nejjednodušší × N: jedna funkce pro všech 32 formátů
Dalším stupněm stručnosti je použití téže funkce bez ohledu na to, který formát cílíte. Protože saveOption lze vypočítat z přípony výstupního souboru, vytažení tohoto odvození ven poskytuje „univerzální převodník souborů“:
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")
}
Použití zůstává stejné — mění se pouze výstupní přípona:
$ 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
Co je to za prázdný import _ "…/register"?
Existují dva způsoby, jak získat saveOption; to je jediný koncept, který musí styl “most concise” pochopit:
- Vyhledejte v registru podle názvu formátu (
formats.Get): rozšíření musí být přítomno v registruformats. Každý podbalíčeksaveoptions/*se zaregistruje ve své vlastní funkciinit(), ale pouze při importu. Importujte podbalíčky, které potřebujete, jeden po druhém (např. jenpdf, pokud převádíte do PDF), nebo prázdný import…/registerjednou, který zaregistruje všech 32 formátů najednou — „universal converter“ výše se spoléhal na tento jediný řádek. - Volání konstruktoru přímo (
pdf.New(),markdown.New()): obejde registr, není potřeba importregister; náklady jsou jeden řádek importu na každý formát, který používáte.
Stručně řečeno: použijte _ "…/register" pouze tehdy, když řešíte pomocí formats.Get + výstupní přípona; předání konstruktoru přímo nevyžaduje nic dalšího. Prázdný import je neškodný a je vždy přítomen v oficiálních příkladech.
3. Nejvíce flexibilní: otáčejte každý knoflík samostatně
Když potřeba přesahuje „soubor na soubor s výchozími nastaveními“, neměníte API — tři parametry Convert jsou nezávisle zaměnitelné.
1. Vstup (zdroj): ze souboru, do paměti, do libovolného streamu
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, …)
Poznámka: podkladový engine vyžaduje náhodný přístup k celému obsahu, takže
ReaderSourcepři prvním přístupu plně načte stream do vyrovnávací paměti; každé další voláníOpenposkytne kopii této vyrovnávací paměti. Používejte jej s důvěrou pro HTTP, jen vězte, že to není pravé „převádění během streamování“.
2. Formát (saveOption): výchozí, nebo vyladěné
| Scenario | Writing style | Why |
|---|---|---|
| Formát s výchozím nastavením | formats.Get("pdf") | vyhledáno podle přípony; nerozlišuje velká a malá písmena; nil pokud není registrováno |
| Formát s možnostmi specifickými pro formát | pdf.New(pdf.WithOnePagePerSheet(true)) | funkční volby |
| Výchozí nastavení, explicitní formát | ooxml.New() / csv.New() / … | jeden konstruktor bez argumentů pro každý formát |
| Vlastní soukromý formát | formats.Register("fmt", factory) | připojit do registru — viz docs/register.md |
Funkční možnosti se objevují pouze u formátů, které je mají: jedna stránka na list v PDF je WithOnePagePerSheet; obrázky vložené do HTML jsou WithExportImagesAsBase64; TSV je formats.Get("tsv"). Možnosti mají semantiku ukazatele: vynechat = výchozí nastavení enginu; předání false explicitně také počítá.
3. Výstup (sink): soubor, bajty nebo 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 a WriterSink jsou dva klíče k „největší flexibilitě“: umožňují, aby výsledek konverze úplně obešel disk a proudil přímo do HTTP odpovědi, úložiště objektů, zipu a podobně. Všechny tři jsou různé implementace stejného parametru sink, takže cokoliv, co přijímá []byte nebo io.Writer, může být zapojeno do konvertoru.
4. Příklady v reálném prostředí: jeden Convert, mnoho tvarů
A. Převod v paměti; koncový bod pro stahování streamuje PDF
Běžný scénář na straně serveru — uživatel nahrává xlsx, endpoint vrací PDF, žádné dočasné soubory:
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())
}
Chcete-li místo toho poskytovat CSV / Excel / HTML, vyměňte pouze saveOption (například formats.Get("csv")); nic jiného se nezmění.
B. Načtěte jednou, hromadně exportujte do mnoha formátů
Přečtěte vstup jen jednou a poté jej znovu použijte prostřednictvím BytesSource pro libovolný počet výstupů — ideální pro “export každé zprávy”.
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. “Uložit jako” v rámci rodiny tabulek (migrace / kompatibilita)
Migrace formátu v rámci rodiny tabulkových souborů, např. xlsx → xls, xlsx → xlsb, xlsx → ods, a šablony xltx/xltm — stále jeden Convert, pouze se mění 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. Ladit možnosti podle formátu, pouze když je to potřeba
Funkční možnosti se objevují, když potřebujete jemnou kontrolu — všimněte si, že každý níže uvedený volání je skutečné a správně typované:
// 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: pro výstupy do jediného souboru, jako jsou CSV/HTML/image, engine exportuje pouze list, který považuje za „aktivní“ ve výchozím nastavení. Pro řízení rozsahu použijte vlastní možnosti formátu — např.
html.WithExportActiveWorksheetOnly(true)(pouze aktivní list?),html.WithShowAllSheets(true)nebocsv.WithExportAllSheets(true). Kvalita obrazu na úrovni pixelů, výběr přesně toho, které listy jsou vykresleny, a další pokročilé ovládací prvky stále existují na úrovni engine, ale aktuální balíčekimagevystavuje pouze přepínačWithImageType— pokud potřebujete více, sáhněte po podkladovém bindingu; sady nástrojů budou postupně přidávat další možnosti.
E. Dávková konverze v adresáři
Každodenní “převést tuto složku Excel souborů do PDF” úkol se stává velmi krátkým díky odvození přípony:
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. Klasifikace chyb
chyby konvertoru jsou klasifikovatelné sentinelní chyby; spárujte je s errors.Is pro přesné zpracování:
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() vrací každé aktuálně registrované rozšíření (seřazené, souběžně bezpečné) — praktické pro vytvoření seznamu „podporovaných formátů“ nebo nápovědy k chybě.
5. Podporované formáty na první pohled (32 registrovaných ve výchozím nastavení)
| Rodina | Výstupní přípony | Ladící balíček |
|---|---|---|
| Excel | xlsx xlsm xltx xltm xls xlsb | saveoptions/ooxml, xls, xlsb |
| OpenDocument | ods xml dif dbf | saveoptions/ods, xml, dif, dbf |
| Text / data | csv txt tsv json sql | saveoptions/csv, txt, json, sqlScript |
| Dokumenty / rozvržení | pdf docx pptx xps pcl epub | saveoptions/pdf, docx, pptx, xps, pcl, ebook |
| Web | html md | saveoptions/html, markdown |
| Obrázky | png jpg jpeg gif bmp svg emf tif tiff | saveoptions/image |
Aby byl binární soubor úsporný, importujte pouze podbalíky, které používáte (např. pdf); pro pohodlí nebo obecné směrování použijte prázdný import …/register. Import podbalíku spustí jeho registraci; vyhledávání v registru není citlivé na velikost písmen; neregistrovaná přípona vrátí nil (ne chybu), což ponechává rozhodnutí o záložním řešení na volajícím.
6. Nejlepší postupy a úskalí
Jedno vstupní místo — nepřepisujte jej. File-to-file používá
Convert(FilePathSource, formats.Get(ext)/constructor, FilePathSink); přepínejte sinky jen když potřebujete bajty nebo stream. Nepište ručněos.Open → ReadAll → … → os.WriteFile; source/sink spravují prostředky a vytvoří nadřazené adresáře za vás.Souběžnost a licencování. Podkladový engine je nativní: nedílejte jeden objekt
SaveOption/workbook mezi goroutine v rámci stejného procesu; pro hromadnou práci zpracovávejte soubory sekvenčně nebo paralelně napříč procesy. Vyhodnocovací sestavení omezuje načítání (přibližně sto načteníNewWorkbook_Streamna proces) — pro velké benchmarky restartujte proces, aby se čítač vynuloval.Přečtěte vstup jednou a poté jej znovu použijte. Pro vytvoření několika formátů z jednoho vstupu jej nejprve
os.ReadFilenačtěte do[]bytea opakovaně převádějte pomocíBytesSource, čímž se vyhnete opakovaným čtením z disku a opětovnému načítání.Streamy jsou bufferovány.
NewReaderSourcebufferuje při prvním přístupu, takže je vhodný pro jednorázové vstupy jako tělo HTTP požadavku, nikoli pro skutečný streaming velmi velkých souborů (pro ty použijteFilePathSource, který ukazuje přímo na disk).Vězte, kdo rozhoduje o rozložení výstupu.
Convertje „jeden vstup → jeden výstupní soubor“. Pokud potřebujete jeden soubor na list nebo zip, použijtemanipulator.SplitsFolderSink/ZipSink— nepřetlačujte to přesConvert.
