ตัวแปลง: หนึ่งบรรทัดที่เรียบง่ายที่สุด, ทุกสภาพแวดล้อมที่ยืดหยุ่นที่สุด
The converter package of Aspose.Cells for Go via C++ Toolkits reduces every “การแปลงสเปรดชีตเป็นรูปแบบอื่น” need to ฟังก์ชันเริ่มต้นเดียว:
converter.Convert(source, saveOption, sink) error
มันมีเพียงสามพารามิเตอร์เท่านั้น และแต่ละพารามิเตอร์ตอบคำถามได้อย่างแม่นยำหนึ่งคำถาม:
| พารามิเตอร์ | ชนิด | คำถามที่ตอบ | ค่าตัวอย่างทั่วไป |
|---|---|---|---|
source | datasource.DataSource | ข้อมูลเข้าเข้ามาจากที่ไหน? | FilePathSource(path), BytesSource(data), NewReaderSource(r) |
saveOption | saveoptions.SaveOption | ผลลัพธ์เป็นอะไรและปรับแต่งอย่างไร? | formats.Get("pdf") for defaults by name, or pdf.New(pdf.WithOnePagePerSheet(true)) for fine control |
sink | datasource.DataSink | ผลลัพธ์จะไปที่ไหน? | FilePathSink(path), &BytesSink{}, NewWriterSink(w) |
สำหรับสไตล์ ที่กระชับที่สุด, ให้ใช้ค่าเริ่มต้นในทุกแกนทั้งสาม; สำหรับ ที่ยืดหยุ่นที่สุด, ปรับแต่ละตัวควบคุมแยกกัน. เนื่องจากแกนทั้งสามเป็นอิสระกัน, ฟังก์ชัน Convert เดียวกันจึงเหมาะกับสภาพแวดล้อมไฟล์, หน่วยความจำ, HTTP และ batch อย่างเป็นธรรมชาติ. (ยังมีคำสั่งแบบบรรทัดเดียวแบบเก่า ConvertSpreadsheetToFile สำหรับกรณีไฟล์→ไฟล์ธรรมดา — เปรียบเทียบในส่วนที่ 1 ด้านล่าง.) ส่วนที่เหลือของบทความนี้จะย้ายจากสไตล์ที่กระชับที่สุดไปสู่สไตล์ที่ยืดหยุ่นที่สุด, โดยขยายโค้ดตัวอย่างเดิมในแต่ละขั้นตอนแทนการสลับไปใช้ API ที่แตกต่าง.
1. ง่ายที่สุด: การเรียกหนึ่งครั้งสำหรับหนึ่งรูปแบบ
1.1 ฟังก์ชันในตัวแบบไฟล์→ไฟล์แบบบรรทัดเดียว: ConvertSpreadsheetToFile
แพ็กเกจยังมาพร้อมกับรายการเก่า ที่สั้นกว่าอีกสำหรับกรณีคลาสสิก “แปลงไฟล์นี้เป็นไฟล์นั้น” เพียงแค่ต้องระบุสองเส้นทาง:
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เป็น wrapper ที่บางเบาซึ่งถูกเก็บไว้เพื่อความเข้ากันได้ย้อนหลัง; โค้ดใหม่จะถูกส่งต่อไปยัง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)
}
}
ตัวควบคุมทั้งสามใช้ค่าเริ่มต้น: input = ไฟล์, format = pdf.New() โดยไม่มีการกำหนดค่า, output = ไฟล์. นั่นคือรูปแบบ “ที่กระชับที่สุด” — ไม่มีการเรียก os.Open/os.Create ด้วยตนเอง, ไม่มีการจัดสรรอ็อบเจกต์, ไม่มีการปิด handle; source/sink จะจัดการทรัพยากรให้คุณ.
1.3 เปรียบเทียบรูปแบบไฟล์→ไฟล์สองแบบ
ConvertSpreadsheetToFile(in, out) | converter.Convert(source, opt, sink) | |
|---|---|---|
| อินพุต | เฉพาะเส้นทางไฟล์ | ใดก็ได้ DataSource: path, []byte, หรือ reader |
| เอาต์พุต | เฉพาะเส้นทางไฟล์ | ใดก็ได้ DataSink: path, bytes, หรือ io.Writer |
| รูปแบบเอาต์พุต | สรุปจากส่วนขยายโดยอัตโนมัติ, ใช้ค่าเริ่มต้นเท่านั้น | ใดก็ได้ saveOption: ค่าเริ่มต้นหรือการปรับแต่งเฉพาะรูปแบบ |
| การนำเข้าเพิ่มเติม | ต้องการให้ลงทะเบียนรูปแบบ (_ "…/register", หรือ subpackage saveoptions/* ที่ตรงกัน) | ไม่มี, เมื่อคุณส่งคอนสตรัคเตอร์เช่น pdf.New() |
| สถานะ | ตัวห่อบางแบบที่เลิกใช้แล้ว (เสถียร, คงไว้เพื่อความเข้ากันได้) | จุดเข้าตรงเดียวที่ระบุในเอกสารสำหรับโค้ดใหม่ |
ไฟล์เดียวกัน → ผลลัพธ์ไฟล์, สองสถานการณ์ที่แตกต่างกัน:
ConvertSpreadsheetToFile— คุณมีเส้นทางสองเส้นโดยตรงและพอใจกับการตั้งค่าเริ่มต้นของเอนจินสำหรับรูปแบบเป้าหมาย. เหมาะสำหรับสคริปต์การแปลงแบบครั้งเดียว, ชุดการย้ายข้อมูล, และตัวช่วยทดสอบ. ข้อเสีย: อินพุต, เอาต์พุต, และการตั้งค่าไม่สามารถออกจากรูปแบบ “file path + defaults” ได้ — และมันถูกยกเลิกการใช้งานแล้ว.converter.Convert— คุณต้องการบรรทัดเดียวเดียวกัน, แต่หนึ่งในสามอาร์กิวเมนต์ใดก็สามารถเปลี่ยนได้: พรุ่งนี้อินพุตอาจเป็น[]byteของการอัปโหลด, เป้าหมายต้องการpdf.WithOnePagePerSheet(true), หรือเอาต์พุตควรส่งตรงไปยังการตอบสนอง HTTP. เหล่านี้คือตัวอย่างสถานการณ์ของส่วนที่ 3 และ 4 — เขียนเพียงครั้งเดียวด้วยConvert, และการเปลี่ยนแปลงแต่ละครั้งเป็นการแก้ไขอาร์กิวเมนต์เดียว.
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; นี่คือแนวคิดเดียวที่สไตล์ “most concise” ต้องเข้าใจ:
- ค้นหาจากรีจิสทรีโดยใช้ชื่อฟอร์แมต (
formats.Get): ส่วนขยายต้องมีอยู่ในรีจิสทรีformatsทุกsaveoptions/*subpackage จะลงทะเบียนตัวเองในinit()ของมันเอง แต่เฉพาะเมื่อถูกนำเข้าเท่านั้น ให้นำเข้า subpackage ที่คุณต้องการทีละอัน (เช่นเฉพาะpdfหากคุณแปลงเป็น PDF) หรือ blank-import…/registerครั้งเดียว, ซึ่งจะลงทะเบียนฟอร์แมตทั้งหมด 32 รูปแบบพร้อมกัน — “universal converter” ด้านบนพึ่งพาบรรทัดเดียวนี้ - เรียกคอนสตรัคเตอร์โดยตรง (
pdf.New(),markdown.New()): ข้ามรีจิสทรี ไม่ต้องนำเข้าregister; ค่าใช้จ่ายคือบรรทัดการนำเข้าหนึ่งบรรทัดต่อฟอร์แมตที่คุณใช้
โดยสรุป: ให้ใช้ _ "…/register" เท่านั้นเมื่อคุณแก้ไขผ่าน formats.Get + ส่วนขยายของผลลัพธ์; การส่งคอนสตรัคเตอร์โดยตรงไม่ต้องการอะไรเพิ่มเติม การนำเข้าแบบว่างเปล่านั้นไม่มีอันตรายและมักปรากฏในตัวอย่างอย่างเป็นทางการเสมอ
3. ที่ยืดหยุ่นที่สุด: ปรับแต่ละปุ่มแยกกัน
เมื่อความต้องการเกินกว่า “file to file with default settings” คุณไม่ต้องเปลี่ยน API — พารามิเตอร์ Convert สามตัวสามารถสลับกันได้อย่างอิสระ.
1. อินพุต (source): จากไฟล์, ไปยังหน่วยความจำ, ไปยังสตรีมใดก็ได้
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): ค่าเริ่มต้น หรือ ปรับแต่ง
| สถานการณ์ | รูปแบบการเขียน | ทำไม |
|---|---|---|
| รูปแบบบางอย่างด้วยการตั้งค่าเริ่มต้น | formats.Get("pdf") | ค้นหาตามส่วนขยาย; ไม่แยกแยะตัวพิมพ์ใหญ่/เล็ก; nil หากไม่ได้ลงทะเบียน |
| รูปแบบที่มีตัวเลือกเฉพาะรูปแบบ | pdf.New(pdf.WithOnePagePerSheet(true)) | ตัวเลือกเชิงฟังก์ชัน |
| การตั้งค่าเริ่มต้น, รูปแบบที่ระบุชัดเจน | ooxml.New() / csv.New() / … | คอนสตรัคเตอร์ศูนย์อาร์กิวเมนต์หนึ่งตัวต่อรูปแบบ |
| รูปแบบส่วนตัวที่กำหนดเอง | formats.Register("fmt", factory) | เชื่อมต่อกับรีจิสทรี — ดู docs/register.md |
ตัวเลือกแบบฟังก์ชันปรากฏเฉพาะในรูปแบบที่มีตัวเลือกเหล่านั้น: หน้าหนึ่งต่อแผ่นงานใน PDF คือ WithOnePagePerSheet; รูปภาพแบบฝังใน HTML คือ WithExportImagesAsBase64; TSV คือ formats.Get("tsv"). ตัวเลือกเป็นแบบ pointer-semantic: ไม่ระบุ = ค่าเริ่มต้นของเอนจิน; การส่งค่า false อย่างชัดเจนก็ถือว่าเป็นการระบุเช่นกัน.
3. ผลลัพธ์ (sink): ไฟล์, ไบต์, หรือ 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 คือกุญแจสองประการที่ทำให้ “ที่ยืดหยุ่นที่สุด”: พวกมันทำให้ผลลัพธ์การแปลงข้ามการเขียนลงดิสก์โดยสมบูรณ์และไหลตรงเข้าสู่การตอบสนอง HTTP, ที่เก็บวัตถุ, ไฟล์ zip, และอื่น ๆ ทั้งสามเป็นการดำเนินการที่แตกต่างกันของพารามิเตอร์ sink เดียวกัน, ดังนั้นสิ่งใดก็ตามที่รับ []byte หรือ io.Writer สามารถเชื่อมต่อกับตัวแปลงได้.
4. ตัวอย่างในสภาพแวดล้อมจริง: หนึ่ง Convert หลายรูปทรง
A. แปลงในหน่วยความจำ; endpoint การดาวน์โหลดสตรีม PDF
สถานการณ์ทั่วไปบนเซิร์ฟเวอร์ — ผู้ใช้อัปโหลดไฟล์ xlsx, endpoint จะส่งกลับเป็น 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 สำหรับผลลัพธ์จำนวนใดก็ได้ — เหมาะสำหรับ “ส่งออกทุกรายงาน”
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. “บันทึกเป็น” ภายในตระกูลสเปรดชีต (การย้าย / ความเข้ากันได้)
การย้ายรูปแบบภายในตระกูลสเปรดชีต เช่น xlsx → xls, xlsx → xlsb, xlsx → ods และเทมเพลต xltx/xltm — ยังเป็นการ 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" / …
เคล็ดลับ: สำหรับการส่งออกแบบไฟล์เดียว เช่น CSV/HTML/image, เอนจินจะส่งออกเฉพาะ worksheet ที่มันพิจารณาว่าเป็น “active” โดยค่าเริ่มต้น หากต้องการควบคุมขอบเขต ให้ใช้ตัวเลือกของรูปแบบเอง — เช่น
html.WithExportActiveWorksheetOnly(true)(only the active sheet?),html.WithShowAllSheets(true), หรือcsv.WithExportAllSheets(true). คุณภาพภาพระดับพิกเซล, การเลือกแผ่นที่ต้องการเรนเดอร์อย่างแม่นยำ, และการควบคุมเชิงลึกอื่น ๆ ยังมีอยู่ที่ระดับเอนจิน แต่แพคเกจimageปัจจุบันเปิดให้ใช้เฉพาะสวิตช์WithImageType— ให้เข้าถึงการผูกพื้นฐานหากต้องการเพิ่มเติม; ชุดเครื่องมือจะค่อย ๆ เพิ่มตัวเลือกเข้ามาตลอดเวลา.
E. การแปลงเป็นชุดบนไดเรกทอรี
งานประจำวัน “convert this folder of Excels to 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. การจัดประเภทข้อผิดพลาด
ข้อผิดพลาดของตัวแปลงเป็นข้อผิดพลาด sentinel ที่สามารถจัดประเภทได้; คู่กับ 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() คืนค่าทุกส่วนขยายที่ลงทะเบียนอยู่ในปัจจุบัน (เรียงลำดับ, ปลอดภัยต่อการทำงานพร้อมกัน) — มีประโยชน์สำหรับการสร้างรายการ “supported formats” หรือเป็นคำแนะนำข้อผิดพลาด
5. รูปแบบที่รองรับในภาพรวม (32 รูปแบบที่ลงทะเบียนโดยค่าเริ่มต้น)
| กลุ่ม | ส่วนขยายผลลัพธ์ | แพคเกจการปรับแต่ง |
|---|---|---|
| Excel | xlsx xlsm xltx xltm xls xlsb | saveoptions/ooxml, xls, xlsb |
| OpenDocument | ods xml dif dbf | saveoptions/ods, xml, dif, dbf |
| ข้อความ / ข้อมูล | csv txt tsv json sql | saveoptions/csv, txt, json, sqlScript |
| เอกสาร / เค้าโครง | pdf docx pptx xps pcl epub | saveoptions/pdf, docx, pptx, xps, pcl, ebook |
| เว็บ | html md | saveoptions/html, markdown |
| รูปภาพ | png jpg jpeg gif bmp svg emf tif tiff | saveoptions/image |
เพื่อให้ไบนารีมีขนาดเล็กลง ให้ import เฉพาะ subpackage ที่คุณใช้ (เช่น pdf); เพื่อความสะดวกหรือการส่งต่อทั่วไป ให้ทำการ blank‑import …/register. การ import subpackage จะทำให้มันลงทะเบียน; การค้นหาใน registry ไม่สนใจตัวพิมพ์ใหญ่‑เล็ก; ส่วนขยายที่ไม่ได้ลงทะเบียนจะคืนค่า nil (ไม่ใช่ข้อผิดพลาด) ทำให้การตัดสินใจ fallback ถูกมอบให้กับผู้เรียกใช้.
6. แนวทางปฏิบัติที่ดีที่สุดและข้อควรระวัง
จุดเข้าหนึ่งเดียว — อย่าประดิษฐ์ใหม่ File-to-file ใช้
Convert(FilePathSource, formats.Get(ext)/constructor, FilePathSink); เปลี่ยน sink เท่านั้นเมื่อคุณต้องการไบต์หรือสตรีม อย่าทำเองos.Open → ReadAll → … → os.WriteFile; source/sink จะจัดการทรัพยากรและสร้างไดเรกทอรีแม่ให้คุณ.การทำงานพร้อมกันและการให้สิทธิ์ เครื่องยนต์พื้นฐานเป็นเนทีฟ: ไม่ ควรแชร์อ็อบเจกต์
SaveOption/workbook ตัวเดียวระหว่าง goroutine ในกระบวนการเดียว; สำหรับงานจำนวนมากให้ประมวลผลไฟล์แบบต่อเนื่องหรือทำแบบขนานผ่านหลายกระบวนการ การสร้างรุ่นประเมินจะจำกัดจำนวนการโหลด (ประมาณหนึ่งร้อยการโหลดNewWorkbook_Streamต่อกระบวนการ) — สำหรับการทดสอบขนาดใหญ่ให้รีสตาร์ทกระบวนการเพื่อรีเซ็ตตัวนับ.อ่านอินพุตครั้งเดียวแล้วใช้ซ้ำ เพื่อสร้างหลายรูปแบบจากอินพุตเดียว, ใช้
os.ReadFileเพื่ออ่านเป็น[]byteก่อนและแปลงซ้ำด้วยBytesSourceเพื่อหลีกเลี่ยงการอ่านดิสก์และโหลดซ้ำหลายครั้ง.สตรีมจะถูกบัฟเฟอร์
NewReaderSourceจะบัฟเฟอร์ในครั้งแรกที่เข้าถึง, ดังนั้นเหมาะกับอินพุตแบบครั้งเดียวเช่น body ของ HTTP request, ไม่ใช่การสตรีมจริงของไฟล์ขนาดใหญ่มาก (ใช้FilePathSourceชี้ตรงไปที่ดิสก์สำหรับกรณีนั้น).รู้ว่าใครเป็นผู้กำหนดรูปแบบผลลัพธ์
Convertคือ “หนึ่งอินพุต → หนึ่งไฟล์ผลลัพธ์”. หากคุณต้องการ ไฟล์หนึ่งต่อเวิร์กชีต หรือ zip, ให้ใช้manipulator.Splitพร้อมFolderSink/ZipSink— อย่าบังคับให้ผ่านConvert.
