support exporting statistics & analysis result, reconciliation statement and import check result to SSV (semicolon separated values) file

This commit is contained in:
MaysWind
2026-02-24 22:59:29 +08:00
parent f9e9c9285f
commit 6d37d42e50
25 changed files with 59 additions and 6 deletions
@@ -234,6 +234,8 @@ export function useReconciliationStatementPageBase() {
if (fileType === KnownFileType.TSV) {
separator = '\t';
} else if (fileType === KnownFileType.SSV) {
separator = ';';
}
const accountBalanceName = isCurrentLiabilityAccount.value ? 'Account Outstanding Balance' : 'Account Balance';
@@ -252,9 +254,9 @@ export function useReconciliationStatementPageBase() {
const rows = transactions.map(transaction => {
const transactionTime = parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transaction.utcOffset);
const type = getDisplayTransactionType(transaction);
let categoryName = transaction.categoryName;
let categoryName = replaceAll(transaction.categoryName, separator, ' ');
let displayAmount = formatAmountToWesternArabicNumeralsWithoutDigitGrouping(transaction.sourceAmount);
let displayAccountName = transaction.sourceAccountName;
let displayAccountName = replaceAll(transaction.sourceAccountName, separator, ' ');
if (transaction.type === TransactionType.ModifyBalance) {
categoryName = tt('Modify Balance');
@@ -263,7 +265,7 @@ export function useReconciliationStatementPageBase() {
}
if (transaction.type === TransactionType.Transfer && transaction.destinationAccount) {
displayAccountName = displayAccountName + ' → ' + (transaction.destinationAccount?.name || '');
displayAccountName = replaceAll(displayAccountName + ' → ' + (transaction.destinationAccount?.name || ''), separator, ' ');
}
let displayAccountBalance = '';
@@ -77,6 +77,11 @@
@click="exportReconciliationStatements(KnownFileType.TSV)">
<v-list-item-title>{{ tt('Export to TSV (Tab-separated values) File') }}</v-list-item-title>
</v-list-item>
<v-list-item :prepend-icon="extendMdiSemicolon"
:disabled="!reconciliationStatements || !reconciliationStatements.transactions || reconciliationStatements.transactions.length < 1"
@click="exportReconciliationStatements(KnownFileType.SSV)">
<v-list-item-title>{{ tt('Export to SSV (Semicolon-separated values) File') }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-btn>
@@ -301,6 +306,9 @@ import { isEquals } from '@/lib/common.ts';
import { getCurrentUnixTime } from '@/lib/datetime.ts';
import { startDownloadFile } from '@/lib/ui/common.ts';
import {
extendMdiSemicolon
} from '@/icons/desktop/extend_mdi_icons.ts';
import {
mdiRefresh,
mdiArrowRight,
@@ -26,6 +26,10 @@
:append-icon="fileFormat === KnownFileType.TSV.extension ? mdiCheck : undefined"
:title="tt('TSV (Tab-separated values) File')"
@click="fileFormat = KnownFileType.TSV.extension"></v-list-item>
<v-list-item :prepend-icon="extendMdiSemicolon"
:append-icon="fileFormat === KnownFileType.SSV.extension ? mdiCheck : undefined"
:title="tt('SSV (Semicolon-separated values) File')"
@click="fileFormat = KnownFileType.SSV.extension"></v-list-item>
<v-list-item :prepend-icon="mdiLanguageMarkdownOutline"
:append-icon="fileFormat === KnownFileType.MARKDOWN.extension ? mdiCheck : undefined"
:title="tt('Markdown File')"
@@ -91,6 +95,9 @@ import { KnownFileType } from '@/core/file.ts';
import { replaceAll } from '@/lib/common.ts';
import { copyTextToClipboard, startDownloadFile } from '@/lib/ui/common.ts';
import {
extendMdiSemicolon
} from '@/icons/desktop/extend_mdi_icons.ts';
import {
mdiDotsVertical,
mdiCheck,
@@ -152,11 +159,13 @@ const dataTableItems = computed<object[]>(() => {
const exportedData = computed<string>(() => {
let ret = '';
if (fileFormat.value === KnownFileType.CSV.extension || fileFormat.value === KnownFileType.TSV.extension) {
if (fileFormat.value === KnownFileType.CSV.extension || fileFormat.value === KnownFileType.TSV.extension || fileFormat.value === KnownFileType.SSV.extension) {
let separator = ',';
if (fileFormat.value === KnownFileType.TSV.extension) {
separator = '\t';
} else if (fileFormat.value === KnownFileType.SSV.extension) {
separator = ';';
}
if (headers.value.length > 0) {
@@ -449,6 +449,9 @@ import {
} from '@/lib/category.ts';
import { startDownloadFile } from '@/lib/ui/common.ts';
import {
extendMdiSemicolon
} from '@/icons/desktop/extend_mdi_icons.ts';
import {
mdiCheck,
mdiArrowRight,
@@ -956,6 +959,12 @@ const toolMenus = computed<ImportTransactionCheckDataMenu[]>(() => [
title: tt('Export to TSV (Tab-separated values) File'),
disabled: isEditing.value || selectedImportTransactionCount.value < 1,
onClick: () => exportData(KnownFileType.TSV)
},
{
prependIcon: extendMdiSemicolon,
title: tt('Export to SSV (Semicolon-separated values) File'),
disabled: isEditing.value || selectedImportTransactionCount.value < 1,
onClick: () => exportData(KnownFileType.SSV)
}
]);
@@ -2147,9 +2156,13 @@ function exportData(fileType: KnownFileType): void {
}
let separator = ',';
let tagSeparator = ';';
if (fileType === KnownFileType.TSV) {
separator = '\t';
} else if (fileType === KnownFileType.SSV) {
separator = ';';
tagSeparator = ',';
}
const header = [
@@ -2203,7 +2216,7 @@ function exportData(fileType: KnownFileType): void {
if (tagName) {
tagName = replaceAll(tagName, separator, ' ');
tagName = replaceAll(tagName, ';', ' ');
tagName = replaceAll(tagName, tagSeparator, ' ');
tagNames.push(tagName);
}
}
@@ -2221,7 +2234,7 @@ function exportData(fileType: KnownFileType): void {
relatedAccountCurrency ?? '',
relatedAmount ?? '',
geographicLocation,
tagNames.join(';'),
tagNames.join(tagSeparator),
replaceAll(transaction.comment || '', separator, ' ')
].join(separator);
});