...
1 package table
2
3 import (
4 "fmt"
5 "strings"
6 "unicode/utf8"
7 )
8
9
10
11
12
13
14
15 func (t *Table) RenderCSV() string {
16 t.initForRender()
17
18 var out strings.Builder
19 if t.numColumns > 0 {
20 if t.title != "" {
21 out.WriteString(t.title)
22 }
23 if t.autoIndex && len(t.rowsHeader) == 0 {
24 t.csvRenderRow(&out, t.getAutoIndexColumnIDs(), renderHint{isAutoIndexRow: true, isHeaderRow: true})
25 }
26 t.csvRenderRows(&out, t.rowsHeader, renderHint{isHeaderRow: true})
27 t.csvRenderRows(&out, t.rows, renderHint{})
28 t.csvRenderRows(&out, t.rowsFooter, renderHint{isFooterRow: true})
29 if t.caption != "" {
30 out.WriteRune('\n')
31 out.WriteString(t.caption)
32 }
33 }
34 return t.render(&out)
35 }
36
37 func (t *Table) csvFixCommas(str string) string {
38 return strings.Replace(str, ",", "\\,", -1)
39 }
40
41 func (t *Table) csvFixDoubleQuotes(str string) string {
42 return strings.Replace(str, "\"", "\\\"", -1)
43 }
44
45 func (t *Table) csvRenderRow(out *strings.Builder, row rowStr, hint renderHint) {
46
47 if out.Len() > 0 {
48 out.WriteRune('\n')
49 }
50
51
52 for colIdx, colStr := range row {
53
54 if colIdx == 0 && t.autoIndex {
55 if hint.isRegularRow() {
56 out.WriteString(fmt.Sprint(hint.rowNumber))
57 }
58 out.WriteRune(',')
59 }
60 if colIdx > 0 {
61 out.WriteRune(',')
62 }
63 if strings.ContainsAny(colStr, "\",\n") {
64 out.WriteRune('"')
65 out.WriteString(t.csvFixCommas(t.csvFixDoubleQuotes(colStr)))
66 out.WriteRune('"')
67 } else if utf8.RuneCountInString(colStr) > 0 {
68 out.WriteString(colStr)
69 }
70 }
71 for colIdx := len(row); colIdx < t.numColumns; colIdx++ {
72 out.WriteRune(',')
73 }
74 }
75
76 func (t *Table) csvRenderRows(out *strings.Builder, rows []rowStr, hint renderHint) {
77 for rowIdx, row := range rows {
78 hint.rowNumber = rowIdx + 1
79 t.csvRenderRow(out, row, hint)
80 }
81 }
82
View as plain text