diff --git a/README.md b/README.md index ec1ca2a..b9df3f0 100644 --- a/README.md +++ b/README.md @@ -4,17 +4,88 @@ [![](https://img.shields.io/badge/📖_How_to_use_DevExpress_Examples-e9f6fc?style=flat-square)](https://docs.devexpress.com/GeneralInformation/403183) [![](https://img.shields.io/badge/💬_Leave_Feedback-feecdd?style=flat-square)](#does-this-example-address-your-development-requirementsobjectives) -# DevExtreme DataGrid and Chart - Export to PDF and Excel +# DevExtreme DataGrid and Chart - Export to a Single File (PDF, XLSX) -This example exports a DataGrid and a related Chart together to PDF and Excel files. +This example exports both the DevExtreme [DataGrid](https://js.devexpress.com/Documentation/Guide/UI_Components/DataGrid/Overview/) and DevExtreme [Chart](https://js.devexpress.com/Documentation/Guide/UI_Components/Chart/Overview/) to a single document (PDF or Excel). -![Example image](images/export-datagrid-chart.png) +![DevExtreme DataGrid and Chart - Export to PDF and Excel example](images/export-datagrid-chart.png) -The main approach is to export both UI components in a coordinated flow: the DataGrid is exported with DevExtreme exporters, and the Chart is converted to an image and inserted into the same output document. +To export components, this example implements a custom interface using DevExtreme [Form](https://js.devexpress.com/Documentation/Guide/UI_Components/Form/Overview/) and [Popup](https://js.devexpress.com/Documentation/Guide/UI_Components/Popup/Overview/) components. Our pre-built UI allows you to configure settings such as page format/PDF orientation, and Chart image offset in Excel. -For PDF export, the example uses [pdfExporter.exportDataGrid](https://js.devexpress.com/jQuery/Documentation/ApiReference/Common/Utils/pdfExporter/) to render the DataGrid with jsPDF and then draws the Chart image below the exported grid so both visuals are included in one file. +## Implementation Details -For Excel export, the example uses [excelExporter.exportDataGrid](https://js.devexpress.com/jQuery/Documentation/ApiReference/Common/Utils/excelExporter/) with ExcelJS, inserts the Chart image into the worksheet, and places it at a configurable row/column offset so you can control layout relative to the grid. +1. Export DataGrid into an in-memory document using the component's built-in export methods: [pdfExporter.exportDataGrid()](https://js.devexpress.com/jQuery/Documentation/ApiReference/Common/Utils/pdfExporter/#exportDataGridoptions) and [excelExporter.exportDataGrid()](https://js.devexpress.com/jQuery/Documentation/ApiReference/Common/Utils/excelExporter/#exportDataGridoptions). +2. Convert Chart to an image using a third-party library (for example, [html-to-image](https://www.npmjs.com/package/html-to-image)). Insert the image into the in-memory document. +3. Save the document to the user's machine. + +### PDF + +```js +function addChartToPDF(pdfDoc, element, x, y, sourceW, sourceH) { + // ... + + return htmlToImage.toPng(element, { + cacheBust: true, + backgroundColor: '#ffffff', + skipFonts: true + }) + .then(function (dataUrl) { + pdfDoc.addImage(dataUrl, 'PNG', x, y, scaledW, scaledH); + }) + // ... +} + +function exportGridToPDF(pageSize, orientation, grid, chart) { + var pdfDoc = new jsPDF(orientation, 'pt', pageSize.toLowerCase()); + // ... + + DevExpress.pdfExporter.exportDataGrid({ + jsPDFDocument: pdfDoc, + // ... + }).then(function () { + var chartEl = chart.element()[0]; + return addChartToPDF(pdfDoc, chartEl, 50, 300, chartEl.scrollWidth, chartEl.scrollHeight); + }).then(function () { + pdfDoc.save('filePDF.pdf'); + }) + // ... +} +``` + +### Excel + +```js +function exportGridToExcel(fileName, imageCol, imageRow, grid, chart) { + var workbook = new ExcelJS.Workbook(); + var worksheet = workbook.addWorksheet('DataGrid'); + + DevExpress.excelExporter.exportDataGrid({ + component: grid, + worksheet: worksheet, + autoFilterEnabled: true + }).then(function (cellRange) { + var chartEl = chart.element()[0]; + + return htmlToImage.toPng(chartEl, { + cacheBust: true, + backgroundColor: '#ffffff', + skipFonts: true + }).then(function (dataUrl) { + var imageId = workbook.addImage({ base64: dataUrl, extension: 'png' }); + worksheet.addImage(imageId, { + tl: { col: imageCol, row: (cellRange.to && cellRange.to.row ? cellRange.to.row : 0) + imageRow }, + ext: { width: 600, height: 400 } + }); + + return workbook.xlsx.writeBuffer(); + }) + // ... + }).then(function (buffer) { + saveAs(new Blob([buffer], { type: 'application/octet-stream' }), fileName + '.xlsx'); + }) + // ... +} +``` ## Files to Review