Dönüştürücü: en basit haliyle bir satır, en esnek ortamda

Aspose.Cells for Go via C++ Toolkits’in converter paketi, her “turn a spreadsheet into another format” ihtiyacını tek bir giriş işlevine indirir:

converter.Convert(source, saveOption, sink) error

Sadece üç parametresi vardır ve her biri tam olarak bir soruya yanıt verir:

ParametreTürCevapladığı soruTipik değerler
sourcedatasource.DataSourceGirdi nereden geliyor?FilePathSource(path), BytesSource(data), NewReaderSource(r)
saveOptionsaveoptions.SaveOptionÇıktı ne olarak, nasıl ayarlanır?formats.Get("pdf") for defaults by name, or pdf.New(pdf.WithOnePagePerSheet(true)) for fine control
sinkdatasource.DataSinkÇıktı nereye gidiyor?FilePathSink(path), &BytesSink{}, NewWriterSink(w)

en öz stil için, üç eksenin tamamında varsayılanı alın; en esnek stil için ise her düğmeyi bağımsız olarak ayarlayın. Üç eksen bağımsız olduğu için aynı Convert doğal olarak dosya, bellek, HTTP ve toplu ortamlarına uyar. (Düz dosya→dosya durumu için ayrıca eski bir tek satırlık ConvertSpreadsheetToFile de vardır — aşağıdaki bölüm 1’de karşılaştırılmıştır.) Bu makalenin geri kalan kısmı en özden en esnek’e doğru ilerleyerek, farklı bir API’ye geçmek yerine önceki kod parçacığını her adımda genişletir.


1. En basit: bir format için bir çağrı

1.1 Yerleşik bir dosya→dosya tek satır: ConvertSpreadsheetToFile

Paket ayrıca klasik “bu dosyayı o dosyaya dönüştür” durumuna yönelik daha eski, daha kısa bir giriş de sunar. Tek ihtiyacı iki yol:

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

Kullanımdan kaldırıldı. ConvertSpreadsheetToFile geriye dönük uyumluluk için tutulan ince bir sarmalayıcıdır; yeni kod aşağıdaki converter.Convert‘a yönlendirilir. Dosya→dosya durumu için ikisi tam olarak eşdeğerdir — ConvertSpreadsheetToFile‘ın yaptığı sadece budur:

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 ve yukarıdaki Convert formu aynı sonuçları üretir; farklı olan senaryodur, aşağıda karşılaştırıldığı gibi.

1.2 Önerilen tek satırlık komut: Convert varsayılanlarla

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

Üç düğmenin tümü varsayılan değerlerini alır: input = bir dosya, format = pdf.New() sıfır yapılandırma ile, output = bir dosya. Bu, “en öz” şekildir — manuel os.Open/os.Create yok, nesne tahsisi yok, tutamaç kapatma yok; kaynak/hedef sizin için kaynakları yönetir.

1.3 İki dosya→dosya şeklinin karşılaştırması

ConvertSpreadsheetToFile(in, out)converter.Convert(source, opt, sink)
Girdiyalnızca bir dosya yoluherhangi bir DataSource: yol, []byte, veya okuyucu
Çıktıyalnızca bir dosya yoluherhangi bir DataSink: yol, baytlar veya io.Writer
Çıktı biçimiher zaman uzantıdan çıkarılır, yalnızca varsayılanlarherhangi bir saveOption: varsayılan veya biçim‑özel ayar
Ek içe aktarmaformatın kayıtlı olması gerekir (_ "…/register", veya eşleşen saveoptions/* alt paketi)yok, pdf.New() gibi bir yapıcı geçirdiğinizde
Durumkullanımdan kaldırılmış ince sarmalayıcı (stabil, uyumluluk için tutulur)yeni kod için belgelenen tek giriş noktası

Aynı dosya→dosya sonucu, iki farklı senaryo:

  • ConvertSpreadsheetToFile — kelimenin tam anlamıyla iki yolunuz var ve hedef format için motorun varsayılan ayarlarından memnunsunuz. Tek seferlik dönüşüm betikleri, taşıma toplulukları ve test yardımcıları için idealdir. Bedeli: giriş, çıkış ve ayarlar asla “dosya yolu + varsayılanlar” biçiminden ayrılamaz — ve bu yöntem artık kullanılmıyor.
  • converter.Convert — aynı tek satır kodu istiyorsunuz, ancak üç argümandan herhangi biri değiştirilebilir: yarın giriş bir yüklemenin []byte‘ı, hedef pdf.WithOnePagePerSheet(true) gerektirebilir veya çıktı doğrudan bir HTTP yanıtına gitmelidir. Bunlar tam olarak bölüm 3 ve 4’teki senaryolardır — Convert ile bir kez yazın ve her değişiklik tek bir argüman düzenlemesi olur.

2. En basit × N: tüm 32 format için tek bir fonksiyon

Bir sonraki düzeyde özlülük, hedeflediğiniz format ne olursa olsun aynı fonksiyonu kullanmaktır. saveOption çıktının dosya uzantısından hesaplanabildiği için, bu çıkarımı dışarı almak bir “evrensel dosya dönüştürücüsü” ortaya çıkar:

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

Kullanım aynı kalır — yalnızca çıktı uzantısı değişir:

$ 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

Boş _ "…/register" içe aktarımı nedir?

Bir saveOption elde etmenin iki yolu vardır; bu, “en öz” stilinin anlaması gereken tek kavramdır:

  • Biçim adına göre kayıttan bakın (formats.Get): uzantının formats kaydında bulunması gerekir. Her saveoptions/* alt paketi kendi init() içinde kendini kaydeder, ancak yalnızca içe aktarıldığında. İhtiyacınız olan alt paketleri tek tek içe aktarın (örneğin PDF’ye dönüştürüyorsanız sadece pdf), ya da boş‑içe‑aktar …/register bir kez, bu da tüm 32 formatı bir kerede kaydeder — yukarıdaki “evrensel dönüştürücü” bu tek satıra dayanır.
  • Bir yapıcıyı doğrudan çağırın (pdf.New(), markdown.New()): kaydı atlar, register içe aktarması gerekmez; maliyet, kullandığınız her format için bir içe aktarma satırıdır.

Kısaca: yalnızca formats.Get + çıktı uzantısı ile çözerken _ "…/register" ifadesini kullanın; bir yapıcıyı doğrudan geçirmek ek bir şey gerektirmez. Boş içe aktarma zararsızdır ve resmi örneklerde her zaman bulunur.

3. En esnek: her düğmeyi bağımsız olarak çevirin

İhtiyaç, “dosyadan dosyaya varsayılan ayarlarla” ifadesinin ötesine geçtiğinde, API’yi değiştirmezsiniz — üç Convert parametresi bağımsız olarak değiştirilebilir.

1. Girdi (kaynak): bir dosyadan, belleğe, herhangi bir akışa

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, …)

Not: temel motor, tüm içeriğe rastgele erişim gerektirir, bu yüzden ReaderSource akışı ilk erişimde tamamen tamponlar; sonraki her Open bu tamponun bir kopyasını sunar. HTTP için güvenle kullanın, sadece bunun gerçek bir “convert while streaming” olmadığını bilin.

2. Biçim (saveOption): varsayılanlar, veya ayarlanmış

SenaryoYazma stiliNeden
Varsayılan ayarlarla bir formatformats.Get("pdf")uzantıya göre aranır; büyük/küçük harfe duyarsız; nil eğer kayıtlı değil
Format‑özel seçeneklere sahip bir formatpdf.New(pdf.WithOnePagePerSheet(true))fonksiyonel seçenekler
Varsayılan ayarlar, açık formatooxml.New() / csv.New() / …her format için sıfır parametreli bir kurucu
Özel bir özel formatformats.Register("fmt", factory)kayıt defterine takın — bakınız docs/register.md

Fonksiyonel seçenekler yalnızca bunlara sahip formatlarda görünür: PDF’de çalışma sayfası başına bir sayfa WithOnePagePerSheet; HTML’de satır içi görüntüler WithExportImagesAsBase64; TSV ise formats.Get("tsv"). Seçenekler işaretçi‑semantiğine sahiptir: atlamak = motorun varsayılanı; false değerini açıkça geçirmek de sayılır.

3. Çıktı (sink): bir dosya, baytlar veya bir 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 ve WriterSink, “en esnek” olmanın iki anahtarıdır: dönüşüm sonucunun tamamen diski atlayıp doğrudan bir HTTP yanıtına, nesne depolamaya, bir zip dosyasına vb. akmasını sağlar. Üçü de aynı sink parametresinin farklı uygulamalarıdır, bu yüzden []byte veya bir io.Writer kabul eden herhangi bir şey dönüştürücüye bağlanabilir.

4. Gerçek ortam örnekleri: bir Convert, birçok şekil

A. Bellekte dönüştür; indirme uç noktası PDF akıtır

Ortak sunucu‑tarafı senaryo — bir kullanıcı xlsx dosyasını yükler, uç nokta PDF döndürür, geçici dosyalar yok:

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 vermek için, yalnızca saveOption değerini değiştirin (örneğin formats.Get("csv")); başka bir şey değişmez.

B. Tek sefer okuyun, birçok formata toplu dışa aktarın

Girişi yalnızca bir kez okuyun, ardından BytesSource aracılığıyla istediğiniz sayıda çıktıda yeniden kullanın — “her raporu dışa aktar” için idealdir:

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. “Farklı Kaydet” elektronik tablo ailesi içinde (göç / uyumluluk)

Elektronik tablo ailesi içinde format geçişi, ör. xlsx → xls, xlsx → xlsb, xlsx → ods, ve şablonlar xltx/xltm — hâlâ tek bir Convert, sadece saveOption değişir:

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. Biçime göre seçenekleri ayarlayın, yalnızca gerektiğinde

Fonksiyonel seçenekler, ince kontrol gerektiğinde ortaya çıkar — aşağıdaki her çağrının gerçek ve doğru tipte olduğunu unutmayın:

// 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" / …

İpucu: CSV/HTML/görüntü gibi tek dosyalı çıktılar için, motor varsayılan olarak yalnızca “aktif” olarak kabul ettiği çalışma sayfasını dışa aktarır. Kapsamı kontrol etmek için formatın kendi seçeneklerini kullanın — ör. html.WithExportActiveWorksheetOnly(true) (yalnızca aktif sayfa?), html.WithShowAllSheets(true), veya csv.WithExportAllSheets(true). Piksel düzeyinde görüntü kalitesi, tam olarak hangi sayfaların render edileceğinin seçilmesi ve diğer derin kontroller hâlâ motor katmanında mevcuttur, ancak mevcut image paketi yalnızca WithImageType anahtarını ortaya çıkarır — daha fazlasına ihtiyacınız olursa temel bağlamaya başvurun; araç seti zamanla seçenekleri katlamaya devam edecektir.

E. Dizin üzerinde toplu dönüştürme

Günlük “bu klasördeki Excel dosyalarını PDF’ye dönüştür” işi uzantı çıkarımıyla çok kısa hale geliyor:

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. Hataları Sınıflandırma

dönüştürücü hataları sınıflandırılabilir sentinel hatalardır; kesin bir işleme için bunları errors.Is ile eşleştirin:

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() her mevcut kayıtlı uzantıyı (sıralı, eşzamanlı‑güvenli) döndürür — “desteklenen formatlar” listesini oluşturmak veya bir hata ipucu sağlamak için kullanışlıdır.

5. Desteklenen formatlar bir bakışta (varsayılan olarak 32 kayıtlı)

AileÇıktı uzantılarıAyarlama paketi
Excelxlsx xlsm xltx xltm xls xlsbsaveoptions/ooxml, xls, xlsb
OpenDocumentods xml dif dbfsaveoptions/ods, xml, dif, dbf
Metin / vericsv txt tsv json sqlsaveoptions/csv, txt, json, sqlScript
Belgeler / düzenpdf docx pptx xps pcl epubsaveoptions/pdf, docx, pptx, xps, pcl, ebook
Webhtml mdsaveoptions/html, markdown
Görsellerpng jpg jpeg gif bmp svg emf tif tiffsaveoptions/image

İkili dosyayı hafif tutmak için yalnızca kullandığınız alt paketleri içe aktarın (örneğin pdf); kolaylık veya genel yönlendirme için boş içe aktarma …/register kullanın. Bir alt paketi içe aktarmak kaydını tetikler; kayıt sorgulamaları büyük/küçük harfe duyarsızdır; kayıtsız bir uzantı nil döndürür (hata değil), geri dönüş kararını çağırana bırakır.


6. En iyi uygulamalar ve uyarılar

  1. Tek giriş noktası — yeniden icat etmeyin. Dosyadan dosyaya Convert(FilePathSource, formats.Get(ext)/constructor, FilePathSink) kullanır; yalnızca baytlara veya bir akışa ihtiyacınız olduğunda hedefleri değiştirin. os.Open → ReadAll → … → os.WriteFile gibi elle kod yazmayın; kaynak/hedef kaynakları yönetir ve sizin için üst dizinleri oluşturur.
  2. Eşzamanlılık ve lisanslama. Temel motor yerel: aynı süreçteki goroutine’lar arasında bir SaveOption/workbook nesnesini paylaşmayın; toplu işler için dosyaları sıralı işleyin veya süreçler arasında paralelleştirin. Değerlendirme sürümü yüklemeleri sınırlıyor (süreç başına yaklaşık yüz NewWorkbook_Stream yüklemesi) — büyük benchmark’lar için sayacı sıfırlamak amacıyla süreci yeniden başlatın.
  3. Girişi bir kez okuyun, ardından yeniden kullanın. Tek bir girdi üzerinden birden fazla format üretmek için, önce os.ReadFile ile bir []byte‘a okuyun ve BytesSource ile tekrar tekrar dönüştürün; böylece tekrarlı disk okuma ve yeniden yüklemelerden kaçınırsınız.
  4. Akışlar tamponlanır. NewReaderSource ilk erişimde tamponlar, bu yüzden bir HTTP istek gövdesi gibi tek seferlik girdiler için uygundur, çok büyük dosyaların gerçek akışı için değil (bunun için doğrudan diske işaret eden FilePathSource kullanın).
  5. Çıktı düzenini kimin belirlediğini bilin. Convert “bir girdi → bir çıktı dosyası"dır. Her çalışma sayfası için bir dosya veya bir zip gerekiyorsa, bu manipulator.Split ile bir FolderSink/ZipSink kullanmak demektir — bunu Convert aracılığıyla zorlamayın.