feat: excel custom data type export
This commit is contained in:
@@ -1,39 +1,42 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import {Events} from "@wailsio/runtime";
|
||||
import { ref, onMounted } from "vue";
|
||||
import { Events } from "@wailsio/runtime";
|
||||
import * as PostService from "../../bindings/app/internal/services/postservice";
|
||||
|
||||
const name = ref('')
|
||||
const result = ref('Please enter your name below 👇')
|
||||
const time = ref('Listening for Time event...')
|
||||
const name = ref("");
|
||||
const result = ref("Please enter your name below 👇");
|
||||
const time = ref("Listening for Time event...");
|
||||
|
||||
const doGreet = () => {
|
||||
let localName = name.value;
|
||||
if (!localName) {
|
||||
localName = 'anonymous';
|
||||
}
|
||||
}
|
||||
let localName = name.value;
|
||||
if (!localName) {
|
||||
localName = "anonymous";
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
console.log(await PostService.GetById(5))
|
||||
await PostService.ExportToExcel()
|
||||
})
|
||||
|
||||
console.log(await PostService.GetById(5));
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>Kuzbass</h1>
|
||||
<h1>Kuzbass</h1>
|
||||
|
||||
<div class="result"></div>
|
||||
<div class="card">
|
||||
<div class="input-box">
|
||||
<input class="input" v-model="name" type="text" autocomplete="off"/>
|
||||
<button class="btn" @click="doGreet">Greet</button>
|
||||
<div class="result"></div>
|
||||
<div class="card">
|
||||
<div class="input-box">
|
||||
<input
|
||||
class="input"
|
||||
v-model="name"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<button class="btn" @click="doGreet">Greet</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<div><p>Click on the Wails logo to learn more</p></div>
|
||||
<div><p></p></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div><p>Click on the Wails logo to learn more</p></div>
|
||||
<div><p></p></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"log/slog"
|
||||
"reflect"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TableHeaders struct {
|
||||
@@ -56,22 +58,34 @@ func ExportEntityToSpreadsheet[T any](filename, sheetName string, entity T, prov
|
||||
// TODO: appearance
|
||||
for i, item := range items {
|
||||
structValue := reflect.ValueOf(item).Elem()
|
||||
for j := range structValue.NumField() {
|
||||
|
||||
for j := 0; j < structValue.NumField(); j++ {
|
||||
if slices.Contains(headers.IgnoredFieldsIndices, j) {
|
||||
continue
|
||||
}
|
||||
field := structValue.Field(j)
|
||||
|
||||
if isPrimitive(field.Type()) {
|
||||
fieldValue := reflect.ValueOf(field)
|
||||
|
||||
fieldValue := field.Interface()
|
||||
cellName, err := GetCellNameByIndices(j, i+1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Field %s value: %v\n", cellName, fieldValue.Interface())
|
||||
|
||||
err = file.SetCellValue(sheetName, cellName, fieldValue.Interface())
|
||||
cellType := structValue.Type().Field(j).Tag.Get(CellTypeTag)
|
||||
|
||||
var cellValue any
|
||||
|
||||
switch cellType {
|
||||
case TimestampTag:
|
||||
cellValue = time.Unix(field.Int(), 0)
|
||||
case DurationTag:
|
||||
cellValue = time.Duration(field.Int())
|
||||
default:
|
||||
cellValue = fieldValue
|
||||
}
|
||||
|
||||
slog.Debug("Field %s value: %v, %s\n", cellName, cellValue, cellType)
|
||||
err = file.SetCellValue(sheetName, cellName, cellValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -79,12 +93,7 @@ func ExportEntityToSpreadsheet[T any](filename, sheetName string, entity T, prov
|
||||
}
|
||||
}
|
||||
|
||||
filepath, err := dialogs.SaveFileDialog("Экспорт данных", filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := file.SaveAs(filepath); err != nil {
|
||||
if err := WriteData(file, filename); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -214,6 +223,18 @@ func ApplyStyleHeaders(file *excelize.File, sheetName string, headers TableHeade
|
||||
return nil
|
||||
}
|
||||
|
||||
func WriteData(file *excelize.File) {
|
||||
func WriteData(file *excelize.File, filename string) error {
|
||||
filepath, err := dialogs.SaveFileDialog("Экспорт данных", filename)
|
||||
|
||||
if !strings.HasSuffix(filepath, ".xlsx") {
|
||||
filepath += ".xlsx"
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := file.SaveAs(filepath); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
10
internal/extras/excel/tags.go
Normal file
10
internal/extras/excel/tags.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package excel
|
||||
|
||||
const (
|
||||
CellTypeTag = "cellType"
|
||||
)
|
||||
|
||||
const (
|
||||
TimestampTag = "timestamp"
|
||||
DurationTag = "duration"
|
||||
)
|
||||
Reference in New Issue
Block a user