feat(export): configurable CSV field quoting mode

This commit is contained in:
zipg authored and GitHub committed 2026-09-03 17:51:50 +08:00
1 parent d421bd33fc
commit 203eab3dec
32 files changed
+442 -56

No files matched your search

@@ -756,7 +756,7 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
}
outputPath = path as string;
}
await api.exportQueryResultCsv(outputPath, result.columns, rows);
await api.exportQueryResultCsv(outputPath, result.columns, rows, useSettingsStore().editorSettings.csvQuoteMode);
if (needsFullExport && exportProgressState) {
exportProgressState.value = {
...exportProgressState.value,
@@ -795,7 +795,7 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
outputPath = path as string;
}
const result = await resultToExport(undefined, undefined, false);
await api.exportQueryResultCsv(outputPath, result.columns, result.rows);
await api.exportQueryResultCsv(outputPath, result.columns, result.rows, useSettingsStore().editorSettings.csvQuoteMode);
toast(t("grid.exported"));
} catch (e: any) {
toast(t("grid.exportFailed", { message: translateBackendError(t, e) }), 5000);
@@ -1154,6 +1154,7 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
tableName: meta.tableName,
filePath: outputPath,
format,
csvQuoteMode: editorSettings.csvQuoteMode,
columns: columns.value,
columnTypes: columnTypes.value,
columnComments: format === "xlsx" ? buildXlsxHeaderOverrides(columns.value, visibleXlsxColumnComments.value, headerMode) : undefined,
@@ -1227,7 +1228,14 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
});
const columnComments = format === "xlsx" ? buildXlsxHeaderOverrides(allColumns.value, allXlsxColumnComments.value, headerMode) : undefined;
const request = baseRequest
? { ...baseRequest, dateTimeFormat: useSettingsStore().editorSettings.globalDateTimeExportFormat || undefined, numericColumnRightAlign: useSettingsStore().editorSettings.numericColumnRightAlign ?? true, columnComments, autoFilter: format === "xlsx" ? autoFilter : undefined }
? {
...baseRequest,
csvQuoteMode: useSettingsStore().editorSettings.csvQuoteMode,
dateTimeFormat: useSettingsStore().editorSettings.globalDateTimeExportFormat || undefined,
numericColumnRightAlign: useSettingsStore().editorSettings.numericColumnRightAlign ?? true,
columnComments,
autoFilter: format === "xlsx" ? autoFilter : undefined,
}
: undefined;
if (!request) throw new Error("Unable to build query result export request");
@@ -18,6 +18,7 @@ import { fetchTableDataForExport } from "@/lib/table/tableDataExport";
import XlsxHeaderDialog from "@/components/export/XlsxHeaderDialog.vue";
import { buildXlsxHeaderOverrides, hasXlsxHeaderComments, type XlsxExportOptions, type XlsxHeaderMode } from "@/lib/export/xlsxHeader";
import { isLoadingStructurePreview, showStructureDocCopyDialog, showStructurePreviewDialog, structureDocCopyText, structureDocCopyTitle, structurePreviewDefaultFileName, structurePreviewError, structurePreviewSql, structurePreviewTitle } from "@/components/sidebar/sidebarTreeDialogState";
import type { CsvQuoteMode } from "@/lib/export/csvQuoteMode";
type StructureCopyFormat = "tsv" | "markdown";
@@ -42,6 +43,7 @@ interface SidebarTableExportTarget {
identifierQuote?: string;
batchSize: number;
rowLimit: number | null;
csvQuoteMode: CsvQuoteMode;
fileNameBase?: string;
}
@@ -360,6 +362,7 @@ export function useSidebarTreeExportRuntime(options: SidebarTreeExportRuntimeOpt
identifierQuote: connectionStore.connectionIdentifierQuote(connectionId),
batchSize: editorSettings.exportBatchSize,
rowLimit: editorSettings.exportRowLimitEnabled ? editorSettings.exportRowLimit : null,
csvQuoteMode: editorSettings.csvQuoteMode,
};
}
@@ -395,7 +398,7 @@ export function useSidebarTreeExportRuntime(options: SidebarTreeExportRuntimeOpt
executePage: (sql) => api.executeQuery(connectionId, database, sql),
});
if (format === "csv") {
await api.exportQueryResultCsv(outputPath, result.columns, result.rows);
await api.exportQueryResultCsv(outputPath, result.columns, result.rows, target.csvQuoteMode);
} else {
const comments = result.columns.map((name) => exportColumnInfos?.find((column) => column.name.toLocaleLowerCase() === name.toLocaleLowerCase())?.comment);
const headerOverrides = buildXlsxHeaderOverrides(result.columns, comments, headerMode);
@@ -424,6 +427,7 @@ export function useSidebarTreeExportRuntime(options: SidebarTreeExportRuntimeOpt
tableName: target.tableName,
filePath: outputPath,
format,
csvQuoteMode: target.csvQuoteMode,
columns: queryColumns,
columnComments,
autoFilter: format === "xlsx" ? autoFilter : undefined,