Fix #3: コメントを追加
All checks were successful
CI / test (push) Successful in 8s
Release / release (push) Successful in 1m23s

This commit is contained in:
2026-06-27 18:26:52 +09:00
parent f47a7283d7
commit 73468e84b6

View File

@@ -95,6 +95,9 @@ Notes:
}
var out []byte
// Use table as the common representation whenever either side is a
// spreadsheet-like format. Structured formats can then share the same
// flatten/restore path for CSV, TSV, and XLSX.
if isTabular(opt.from) && isTabular(opt.to) {
t, err := parseTable(input, opt.from, opt.sheet)
if err != nil {
@@ -366,6 +369,8 @@ func writeXLSX(t table, sheet string) ([]byte, error) {
}
}
if len(t.Header) > 0 {
// The generated workbook is meant for editing, so keep the header row
// visible and visually distinct.
end, _ := excelize.CoordinatesToCellName(len(t.Header), 1)
style, _ := f.NewStyle(&excelize.Style{Font: &excelize.Font{Bold: true}})
_ = f.SetCellStyle(sheet, "A1", end, style)
@@ -401,6 +406,7 @@ func valueToTable(value any) table {
}
flatRows = append(flatRows, flat)
}
// Stable column ordering keeps generated CSV/TSV/XLSX diffs predictable.
sort.Strings(header)
rows := make([][]string, 0, len(flatRows))
for _, flat := range flatRows {
@@ -418,6 +424,8 @@ func recordsFromValue(value any) []any {
case []any:
return v
case map[string]any:
// Common wrapper keys let TOML and object-shaped inputs represent a
// table without adding a format-specific flag.
for _, key := range []string{"rows", "records", "items"} {
if rows, ok := v[key].([]any); ok {
return rows
@@ -429,6 +437,8 @@ func recordsFromValue(value any) []any {
}
}
// flatten converts nested values into spreadsheet-safe column paths such as
// user.name and items[0].sku.
func flatten(prefix string, value any, out map[string]string) {
switch v := value.(type) {
case map[string]any:
@@ -485,6 +495,8 @@ func scalarString(value any) string {
}
}
// tableToRecords restores each row by interpreting header cells as path
// expressions. Empty headers are ignored so spare spreadsheet columns are safe.
func tableToRecords(t table) []map[string]any {
var records []map[string]any
for _, row := range t.Rows {
@@ -501,6 +513,8 @@ func tableToRecords(t table) []map[string]any {
return records
}
// parseCell keeps spreadsheet round trips useful while avoiding broad type
// inference that could surprise users editing IDs or codes.
func parseCell(s string) any {
s = strings.TrimSpace(s)
if s == "" {
@@ -523,6 +537,8 @@ func parseCell(s string) any {
var pathTokenRE = regexp.MustCompile(`([^\.\[\]]+)|\[(\d+)\]`)
// setPath creates maps and slices as needed for dotted and indexed header
// paths. Invalid intermediate shapes are left unchanged instead of guessing.
func setPath(root map[string]any, path string, value any) {
tokens := parsePath(path)
if len(tokens) == 0 {