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 = `
`