Skip to content

Commit

Permalink
Harmonize between CSV and Excel export #688
Browse files Browse the repository at this point in the history
  • Loading branch information
Florent FAYOLLE committed Oct 12, 2023
1 parent dc5a8d9 commit f77c789
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 26 deletions.
54 changes: 34 additions & 20 deletions app/server/lib/ExportCSV.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ export async function downloadCSV(activeDoc: ActiveDoc, req: express.Request,
res: express.Response, options: DownloadOptions) {
log.info('Generating .csv file...');
const {filename, tableId, viewSectionId, filters, sortOrder, linkingFilter, colIdAsHeader} = options;
const colPropertyAsHeader = colIdAsHeader ? 'colId' : 'label';
const data = viewSectionId ?
await makeCSVFromViewSection(
activeDoc, viewSectionId, sortOrder || null, filters || null, linkingFilter || null, colPropertyAsHeader, req) :
await makeCSVFromTable(activeDoc, tableId, colPropertyAsHeader, req);
await makeCSVFromViewSection({
activeDoc, viewSectionId, sortOrder: sortOrder || null, filters: filters || null,
linkingFilter: linkingFilter || null, colIdAsHeader, req
}) :
await makeCSVFromTable({activeDoc, tableId, colIdAsHeader, req});
res.set('Content-Type', 'text/csv');
res.setHeader('Content-Disposition', contentDisposition(filename + '.csv'));
res.send(data);
Expand All @@ -33,38 +34,51 @@ export async function downloadCSV(activeDoc: ActiveDoc, req: express.Request,
*
* See https://github.com/wdavidw/node-csv for API details.
*
* @param {Object} activeDoc - the activeDoc that the table being converted belongs to.
* @param {Integer} viewSectionId - id of the viewsection to export.
* @param {Integer[]} activeSortOrder (optional) - overriding sort order.
* @param {Filter[]} filters (optional) - filters defined from ui.
* @param {Object} options - options for the export.
* @param {Object} options.activeDoc - the activeDoc that the table being converted belongs to.
* @param {Integer} options.viewSectionId - id of the viewsection to export.
* @param {Integer[]} options.activeSortOrder (optional) - overriding sort order.
* @param {Filter[]} options.filters (optional) - filters defined from ui.
* @param {FilterColValues} options.linkingFilter (optional) - linking filter defined from ui.
* @param {boolean} [options.colIdAsHeader] - whether to use column id as header.
* @param {express.Request} options.req - the request object.
*
* @return {Promise<string>} Promise for the resulting CSV.
*/
export async function makeCSVFromViewSection(
export async function makeCSVFromViewSection({
activeDoc, viewSectionId, sortOrder = null, filters = null, linkingFilter = null, colIdAsHeader, req
}: {
activeDoc: ActiveDoc,
viewSectionId: number,
sortOrder: number[] | null,
filters: Filter[] | null,
linkingFilter: FilterColValues | null,
colPropertyAsHeader: 'label' | 'colId',
req: express.Request) {
colIdAsHeader?: boolean,
req: express.Request
}) {

const data = await exportSection(activeDoc, viewSectionId, sortOrder, filters, linkingFilter, req);
const file = convertToCsv(data, colPropertyAsHeader);
const file = convertToCsv(data, { colIdAsHeader });
return file;
}

/**
* Returns a csv stream of a table that can be transformed or parsed.
*
* @param {Object} activeDoc - the activeDoc that the table being converted belongs to.
* @param {Integer} tableId - id of the table to export.
* @param {Object} options - options for the export.
* @param {Object} options.activeDoc - the activeDoc that the table being converted belongs to.
* @param {Integer} options.tableId - id of the table to export.
* @param {boolean} [options.colIdAsHeader] - whether to use column id as header.
* @param {express.Request} options.req - the request object.
*
* @return {Promise<string>} Promise for the resulting CSV.
*/
export async function makeCSVFromTable(
export async function makeCSVFromTable({ activeDoc, tableId, colIdAsHeader, req }: {
activeDoc: ActiveDoc,
tableId: string,
colPropertyAsHeader: 'label' | 'colId',
req: express.Request) {
colIdAsHeader?: boolean,
req: express.Request
}) {

if (!activeDoc.docData) {
throw new Error('No docData in active document');
Expand All @@ -79,20 +93,20 @@ export async function makeCSVFromTable(
}

const data = await exportTable(activeDoc, tableRef, req);
const file = convertToCsv(data, colPropertyAsHeader);
const file = convertToCsv(data, { colIdAsHeader });
return file;
}

function convertToCsv({
rowIds,
access,
columns: viewColumns,
docSettings,
}: ExportData, colPropertyAsHeader: 'label' | 'colId') {
}: ExportData, options: { colIdAsHeader?: boolean }) {

// create formatters for columns
const formatters = viewColumns.map(col => col.formatter);
// Arrange the data into a row-indexed matrix, starting with column headers.
const colPropertyAsHeader = options.colIdAsHeader ? 'colId' : 'label';
const csvMatrix = [viewColumns.map(col => col[colPropertyAsHeader])];
// populate all the rows with values as strings
rowIds.forEach(row => {
Expand Down
24 changes: 18 additions & 6 deletions app/server/lib/workerExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,18 @@ export async function doMakeXLSXFromOptions(
}

/**
* @async
* Returns a XLSX stream of a view section that can be transformed or parsed.
*
* @param {Object} activeDoc - the activeDoc that the table being converted belongs to.
* @param {Integer} viewSectionId - id of the viewsection to export.
* @param {Integer[]} activeSortOrder (optional) - overriding sort order.
* @param {Filter[]} filters (optional) - filters defined from ui.
* @param {Object} options - options for the export.
* @param {Object} options.activeDocSource - the activeDoc that the table being converted belongs to.
* @param {Integer} options.viewSectionId - id of the viewsection to export.
* @param {Integer[]} options.activeSortOrder (optional) - overriding sort order.
* @param {Filter[]} options.filters (optional) - filters defined from ui.
* @param {FilterColValues} options.linkingFilter (optional)
* @param {Stream} options.stream - the stream to write to.
* @param {boolean} options.testDates - whether to use static dates for testing.
* @param {boolean} [options.colIdAsHeader] - whether to use column id as header.
*/
async function doMakeXLSXFromViewSection({
activeDocSource, testDates, stream, viewSectionId, sortOrder, filters, linkingFilter, colIdAsHeader
Expand All @@ -117,10 +123,16 @@ async function doMakeXLSXFromViewSection({
}

/**
* @async
* Returns a XLSX stream of a table that can be transformed or parsed.
*
* @param {Object} activeDoc - the activeDoc that the table being converted belongs to.
* @param {Integer} tableId - id of the table to export.
* @param {Object} options - options for the export.
* @param {Object} options.activeDocSource - the activeDoc that the table being converted belongs to.
* @param {Integer} options.tableId - id of the table to export.
* @param {Stream} options.stream - the stream to write to.
* @param {boolean} options.testDates - whether to use static dates for testing.
* @param {boolean} [options.colIdAsHeader] - whether to use column id as header.
*
*/
async function doMakeXLSXFromTable({activeDocSource, testDates, stream, tableId, colIdAsHeader}: {
activeDocSource: ActiveDocSource,
Expand Down

0 comments on commit f77c789

Please sign in to comment.