mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 05:10:31 +00:00
feat: export resource tables to pdf
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { ExportResourceService } from './ExportService';
|
||||
import { ExportFormat } from './common';
|
||||
|
||||
@Service()
|
||||
export class ExportApplication {
|
||||
@@ -9,9 +10,9 @@ export class ExportApplication {
|
||||
/**
|
||||
* Exports the given resource to csv, xlsx or pdf format.
|
||||
* @param {string} reosurce
|
||||
* @param {string} format
|
||||
* @param {ExportFormat} format
|
||||
*/
|
||||
public export(tenantId: number, resource: string, format: string) {
|
||||
public export(tenantId: number, resource: string, format: ExportFormat) {
|
||||
return this.exportResource.export(tenantId, resource, format);
|
||||
}
|
||||
}
|
||||
|
||||
47
packages/server/src/services/Export/ExportPdf.ts
Normal file
47
packages/server/src/services/Export/ExportPdf.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { ChromiumlyTenancy } from '../ChromiumlyTenancy/ChromiumlyTenancy';
|
||||
import { TemplateInjectable } from '../TemplateInjectable/TemplateInjectable';
|
||||
import { mapPdfRows } from './utils';
|
||||
|
||||
@Service()
|
||||
export class ExportPdf {
|
||||
@Inject()
|
||||
private templateInjectable: TemplateInjectable;
|
||||
|
||||
@Inject()
|
||||
private chromiumlyTenancy: ChromiumlyTenancy;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param tenantId
|
||||
* @param columns
|
||||
* @param data
|
||||
* @param sheetTitle
|
||||
* @param sheetDescription
|
||||
* @returns
|
||||
*/
|
||||
public async pdf(
|
||||
tenantId: number,
|
||||
columns: { accessor: string },
|
||||
data: Record<string, any>,
|
||||
sheetTitle: string = '',
|
||||
sheetDescription: string = ''
|
||||
) {
|
||||
const rows = mapPdfRows(columns, data);
|
||||
|
||||
const htmlContent = await this.templateInjectable.render(
|
||||
tenantId,
|
||||
'modules/export-resource-table',
|
||||
{
|
||||
table: { rows, columns },
|
||||
sheetTitle,
|
||||
sheetDescription,
|
||||
}
|
||||
);
|
||||
// Convert the HTML content to PDF
|
||||
return this.chromiumlyTenancy.convertHtmlContent(tenantId, htmlContent, {
|
||||
margins: { top: 0, bottom: 0, left: 0, right: 0 },
|
||||
landscape: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,10 @@ import { sanitizeResourceName } from '../Import/_utils';
|
||||
import ResourceService from '../Resource/ResourceService';
|
||||
import { ExportableResources } from './ExportResources';
|
||||
import { ServiceError } from '@/exceptions';
|
||||
import { Errors } from './common';
|
||||
import { Errors, ExportFormat } from './common';
|
||||
import { IModelMeta, IModelMetaColumn } from '@/interfaces';
|
||||
import { flatDataCollections, getDataAccessor } from './utils';
|
||||
import { ExportPdf } from './ExportPdf';
|
||||
|
||||
@Service()
|
||||
export class ExportResourceService {
|
||||
@@ -18,13 +19,20 @@ export class ExportResourceService {
|
||||
@Inject()
|
||||
private exportableResources: ExportableResources;
|
||||
|
||||
@Inject()
|
||||
private exportPdf: ExportPdf;
|
||||
|
||||
/**
|
||||
* Exports the given resource data through csv, xlsx or pdf.
|
||||
* @param {number} tenantId - Tenant id.
|
||||
* @param {string} resourceName - Resource name.
|
||||
* @param {string} format - File format.
|
||||
* @param {ExportFormat} format - File format.
|
||||
*/
|
||||
public async export(tenantId: number, resourceName: string, format: string = 'csv') {
|
||||
public async export(
|
||||
tenantId: number,
|
||||
resourceName: string,
|
||||
format: ExportFormat = ExportFormat.Csv
|
||||
) {
|
||||
const resource = sanitizeResourceName(resourceName);
|
||||
const resourceMeta = this.getResourceMeta(tenantId, resource);
|
||||
|
||||
@@ -33,9 +41,21 @@ export class ExportResourceService {
|
||||
const data = await this.getExportableData(tenantId, resource);
|
||||
const transformed = this.transformExportedData(tenantId, resource, data);
|
||||
const exportableColumns = this.getExportableColumns(resourceMeta);
|
||||
const workbook = this.createWorkbook(transformed, exportableColumns);
|
||||
|
||||
return this.exportWorkbook(workbook, format);
|
||||
// Returns the csv, xlsx format.
|
||||
if (format === ExportFormat.Csv || format === ExportFormat.Xlsx) {
|
||||
const workbook = this.createWorkbook(transformed, exportableColumns);
|
||||
|
||||
return this.exportWorkbook(workbook, format);
|
||||
// Returns the pdf format.
|
||||
} else if (format === ExportFormat.Pdf) {
|
||||
return this.exportPdf.pdf(
|
||||
tenantId,
|
||||
exportableColumns,
|
||||
transformed,
|
||||
'Accounts'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,6 +111,7 @@ export class ExportResourceService {
|
||||
private async getExportableData(tenantId: number, resource: string) {
|
||||
const exportable =
|
||||
this.exportableResources.registry.getExportable(resource);
|
||||
|
||||
return exportable.exportable(tenantId, {});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
export enum Errors {
|
||||
RESOURCE_NOT_EXPORTABLE = 'RESOURCE_NOT_EXPORTABLE',
|
||||
}
|
||||
|
||||
export enum ExportFormat {
|
||||
Csv = 'csv',
|
||||
Pdf = 'pdf',
|
||||
Xlsx = 'xlsx',
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { flatMap } from 'lodash';
|
||||
import { flatMap, get } from 'lodash';
|
||||
/**
|
||||
* Flattens the data based on a specified attribute.
|
||||
* @param data - The data to be flattened.
|
||||
@@ -25,3 +25,18 @@ export const flatDataCollections = (
|
||||
export const getDataAccessor = (col: any) => {
|
||||
return col.group ? `${col.group}.${col.accessor}` : col.accessor;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param columns
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
export const mapPdfRows = (columns: any, data: Record<string, any>) => {
|
||||
return data.map((item) => {
|
||||
const cells = columns.map((column) => {
|
||||
return { key: column.accessor, value: get(item, column.accessor) };
|
||||
});
|
||||
return { cells, classNames: '' };
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user