package service import ( "archive/zip" "bytes" "encoding/xml" "fmt" "strconv" "strings" ) func exportInboundCardsXLSX(cards []SIMCard) ([]byte, error) { var buf bytes.Buffer zw := zip.NewWriter(&buf) files := map[string]string{ "[Content_Types].xml": contentTypesXML, "_rels/.rels": rootRelsXML, "xl/workbook.xml": workbookXML, "xl/_rels/workbook.xml.rels": workbookRelsXML, "xl/sharedStrings.xml": sharedStringsXML(), "xl/styles.xml": stylesXML, "xl/worksheets/sheet1.xml": sheetXML(cards), } for _, name := range []string{"[Content_Types].xml", "_rels/.rels", "xl/workbook.xml", "xl/_rels/workbook.xml.rels", "xl/sharedStrings.xml", "xl/styles.xml", "xl/worksheets/sheet1.xml"} { w, err := zw.Create(name) if err != nil { return nil, err } if _, err := w.Write([]byte(files[name])); err != nil { return nil, err } } if err := zw.Close(); err != nil { return nil, err } return buf.Bytes(), nil } func sheetXML(cards []SIMCard) string { var b strings.Builder b.WriteString(``) b.WriteString(``) b.WriteString(``) b.WriteString(``) writeSharedStringRow(&b, 1, len(inboundExportHeaders)) for i, card := range cards { row := inboundExportRow(card) values := make([]string, 0, len(inboundExportColumns)) for _, column := range inboundExportColumns { values = append(values, row[column.Key]) } writeSheetRow(&b, i+2, values) } b.WriteString(``) return b.String() } func writeSharedStringRow(b *strings.Builder, rowNum, count int) { b.WriteString(``) for i := 0; i < count; i++ { ref := fmt.Sprintf("%s%d", columnName(i+1), rowNum) b.WriteString(``) b.WriteString(strconv.Itoa(i)) b.WriteString(``) } b.WriteString(``) } func writeSheetRow(b *strings.Builder, rowNum int, values []string) { b.WriteString(``) for i, value := range values { ref := fmt.Sprintf("%s%d", columnName(i+1), rowNum) b.WriteString(``) b.WriteString(xmlEscape(value)) b.WriteString(``) } b.WriteString(``) } func sharedStringsXML() string { var b strings.Builder b.WriteString(``) b.WriteString(``) for _, header := range inboundExportHeaders { b.WriteString(``) b.WriteString(xmlEscape(header)) b.WriteString(``) } b.WriteString(``) return b.String() } func columnName(index int) string { var out []byte for index > 0 { index-- out = append([]byte{byte('A' + index%26)}, out...) index /= 26 } return string(out) } func xmlEscape(value string) string { var b strings.Builder _ = xml.EscapeText(&b, []byte(value)) return b.String() } const contentTypesXML = ` ` const rootRelsXML = ` ` const workbookXML = ` ` const workbookRelsXML = ` ` const stylesXML = ` `