From cae29d9a71d0d8b3b2939aa464c5615f1a228260 Mon Sep 17 00:00:00 2001 From: Romein van Buren Date: Sun, 25 Jun 2023 22:00:53 +0200 Subject: [PATCH] Fixed export to Excel feature, it works now --- internal/app/collection_find_export.go | 95 ++++++++---------- .../contenttypes.xml | 23 ++++- .../collection_find_export_excel/dotrels.xml | 6 ++ .../collection_find_export_excel/metadata.xml | 20 ++++ .../template.xlsx | Bin 0 -> 9142 bytes .../collection_find_export_excel/workbook.xml | 10 ++ 6 files changed, 96 insertions(+), 58 deletions(-) create mode 100644 internal/app/collection_find_export_excel/dotrels.xml create mode 100644 internal/app/collection_find_export_excel/metadata.xml create mode 100644 internal/app/collection_find_export_excel/template.xlsx create mode 100644 internal/app/collection_find_export_excel/workbook.xml diff --git a/internal/app/collection_find_export.go b/internal/app/collection_find_export.go index bb7064b..6fca235 100644 --- a/internal/app/collection_find_export.go +++ b/internal/app/collection_find_export.go @@ -6,7 +6,6 @@ import ( "encoding/csv" "encoding/json" "fmt" - "io" "os" "strings" @@ -43,6 +42,12 @@ var ( excelThemeXml string //go:embed collection_find_export_excel/contenttypes.xml excelContentTypesXml string + //go:embed collection_find_export_excel/metadata.xml + excelMetadataXml string + //go:embed collection_find_export_excel/workbook.xml + excelWorkbookXml string + //go:embed collection_find_export_excel/dotrels.xml + excelDotRelsXml string alphabet = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ") ) @@ -260,8 +265,7 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo var csvWriter *csv.Writer var excelZipWriter *zip.Writer - var excelSheetWriter io.Writer - var excelStrings = make([]string, 0) + var excelSheetWriter strings.Builder switch settings.Format { case ExportFormatJsonArray: @@ -274,12 +278,15 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo excelZipWriter = zip.NewWriter(file) files := map[string]string{ - "docProps/app.xml": excelAppXml, - "docProps/core.xml": strings.Replace(excelCoreXml, "{TITLE}", fmt.Sprintf("%s.%s", dbKey, collKey), 1), - "xl/theme/theme1.xml": excelThemeXml, - "xl/rels/workbook.xml.rels": excelRelsXml, - "xl/styles.xml": excelStylesXml, - "[Content-Types].xml": excelContentTypesXml, + "_rels/.rels": excelDotRelsXml, + "docProps/app.xml": excelAppXml, + "docProps/core.xml": strings.Replace(excelCoreXml, "{TITLE}", fmt.Sprintf("%s.%s", dbKey, collKey), 1), + "xl/_rels/workbook.xml.rels": excelRelsXml, + "xl/theme/theme1.xml": excelThemeXml, + "xl/metadata.xml": excelMetadataXml, + "xl/styles.xml": excelStylesXml, + "xl/workbook.xml": excelWorkbookXml, + "[Content_Types].xml": excelContentTypesXml, } for fname, body := range files { @@ -306,36 +313,7 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo } } - excelZipWriter.Create("_rels/") - - excelSheetWriter, err = excelZipWriter.Create("xl/worksheets/sheet1.xml") - if err != nil { - runtime.LogErrorf(a.ctx, "Export: Excel ZIP error creating worksheet: %s", err.Error()) - runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ - Title: "ZIP error!", - Message: err.Error(), - Type: runtime.ErrorDialog, - }) - return false - } - - excelSheetWriter.Write([]byte(` - - - - - - - - - `)) + excelSheetWriter = strings.Builder{} } for cur.Next(ctx) { @@ -388,9 +366,7 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo case ExportFormatExcel: excelSheetWriter.Write([]byte(fmt.Sprintf(``, len(columnKeys)))) for idx, key := range columnKeys { - // excelStringsWriter.Write([]byte(fmt.Sprintf("%s", key))) - excelStrings = append(excelStrings, key) - excelSheetWriter.Write([]byte(fmt.Sprintf(`%d`, excelColIndex(idx+1), len(excelStrings)))) + excelSheetWriter.Write([]byte(fmt.Sprintf(`%s`, excelColIndex(idx+1), key))) } excelSheetWriter.Write([]byte("")) } @@ -485,9 +461,7 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo excelSheetWriter.Write([]byte(fmt.Sprintf(``, index+2, len(columnKeys)))) for idx, val := range excelRow { - // excelStringsWriter.Write([]byte(fmt.Sprintf("%s", val))) - excelStrings = append(excelStrings, val) - excelSheetWriter.Write([]byte(fmt.Sprintf(`%d`, excelColIndex(idx+1), index+2, len(excelStrings)))) + excelSheetWriter.Write([]byte(fmt.Sprintf(`%s`, excelColIndex(idx+1), index+2, val))) } excelSheetWriter.Write([]byte("")) } @@ -500,11 +474,9 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo file.WriteString("]\n") case ExportFormatExcel: - excelSheetWriter.Write([]byte(``)) - - excelStringsWriter, err := excelZipWriter.Create("xl/sharedStrings.xml") + sw, err := excelZipWriter.Create("xl/worksheets/sheet1.xml") if err != nil { - runtime.LogErrorf(a.ctx, "Export: Excel ZIP error creating shared strings: %s", err.Error()) + runtime.LogErrorf(a.ctx, "Export: Excel ZIP error creating worksheet: %s", err.Error()) runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ Title: "ZIP error!", Message: err.Error(), @@ -513,13 +485,26 @@ func (a *App) PerformFindExport(hostKey, dbKey, collKey, settingsJson string) bo return false } - excelStringsWriter.Write([]byte(fmt.Sprintf(`%s`, len(excelStrings), len(excelStrings), "\r\n"))) - for _, str := range excelStrings { - excelStringsWriter.Write([]byte(fmt.Sprintf("%s\r\n", str))) - } - excelStringsWriter.Write([]byte("")) + sw.Write([]byte(strings.ReplaceAll(fmt.Sprintf(` + + + + + + + `, excelColIndex(len(columnKeys)), index+1), "\n", "\r\n"))) + sw.Write([]byte(excelSheetWriter.String())) + sw.Write([]byte(``)) - if err := excelZipWriter.Close(); err != nil { + err = excelZipWriter.Close() + if err != nil { runtime.LogErrorf(a.ctx, "Export: Excel ZIP error while closing: %s", err.Error()) runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ Title: "ZIP error!", diff --git a/internal/app/collection_find_export_excel/contenttypes.xml b/internal/app/collection_find_export_excel/contenttypes.xml index 2312f21..8a41e3f 100644 --- a/internal/app/collection_find_export_excel/contenttypes.xml +++ b/internal/app/collection_find_export_excel/contenttypes.xml @@ -1,12 +1,29 @@ - - + + + + + + + + + + + + + + + - + diff --git a/internal/app/collection_find_export_excel/dotrels.xml b/internal/app/collection_find_export_excel/dotrels.xml new file mode 100644 index 0000000..a719722 --- /dev/null +++ b/internal/app/collection_find_export_excel/dotrels.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/internal/app/collection_find_export_excel/metadata.xml b/internal/app/collection_find_export_excel/metadata.xml new file mode 100644 index 0000000..99f5b57 --- /dev/null +++ b/internal/app/collection_find_export_excel/metadata.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/internal/app/collection_find_export_excel/template.xlsx b/internal/app/collection_find_export_excel/template.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..0a4518fa6b1e08316e971a5fb5d1f5f65b522465 GIT binary patch literal 9142 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 literal 0 HcmV?d00001 diff --git a/internal/app/collection_find_export_excel/workbook.xml b/internal/app/collection_find_export_excel/workbook.xml new file mode 100644 index 0000000..6b4c93a --- /dev/null +++ b/internal/app/collection_find_export_excel/workbook.xml @@ -0,0 +1,10 @@ + + + + + + +