Download excel sheet with image in Android
Create new project with your suitable Stack.
Here I gonna use Angular with Capacitor JS, so that we can go with both web and for mobile app. View Capacitor JS documentation to get started with it - https://capacitorjs.com/docs/v3/getting-started. After setting up capacitor,
- Add exceljs plugin from npm as dependency
npm i exceljs
- Lets create a workbook (i.e excel sheet) and add some heading and style into it
/// Excel Title, Header, Data
const title = 'Employee List';
const header = ["S No", "Employee Name", "Age", "Image"];
/// Create workbook and worksheet
let workbook = new Workbook();
let worksheet = workbook.addWorksheet('list');
/// Header Part
let titleRow = worksheet.addRow([title]);
worksheet.mergeCells('A1:D1');
titleRow.font = { bold: true };
worksheet.addRow([]);
let headerRow = worksheet.addRow(header);
headerRow.eachCell((cell, number) => {
cell.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FFFFFF00' },
bgColor: { argb: 'FF0000FF' }
}
})
You can refer exceljs
documentation to implement style and other properties.
- Inserting image into a cell:
You can add image using addImage
in any of the following format
filename
- Directly access to filepath of the image
buffer
- Add file buffer [ Eg: fs.readFileSync(path) ]
base64
- You can add image even by converting it to base64 date
Valid extension of images values are 'jpeg', 'png', 'gif'
.
Note: You can also use addBackgroundImage
to insert image as background
let image = workbook.addImage({
base64: "data:image/jpeg;base64," + base64Image.data,
extension: 'jpeg',
});
var range = 'A3:B3';
worksheet.addImage(image, range);
The cell range can also have the property 'editAs' which will control how the image is anchored to the cell(s). It can have one of the following values:
oneCell - (default) Image will be moved with cells but not sized
undefined - It specifies the image will be moved and sized with cells
absolute - Image will not be moved or sized with cells
Additionally you can specify the height, width and even add hyperlink to that image.
- Lets create a Angular Service to get download excel file and open it. Here we go a full service file example of employee list with employee image
import { Injectable } from '@angular/core';
import { Workbook } from 'exceljs';
import { Plugins, FilesystemDirectory, FilesystemEncoding, Capacitor } from '@capacitor/core';
const { Filesystem } = Plugins;
import { FileOpener } from '@ionic-native/file-opener/ngx';
@Injectable({
providedIn: 'root'
})
export class ExcelService {
base64data: any;
constructor(private fileOpener: FileOpener) { }
async generateExcel() {
/// Excel Title, Header, Data
const title = 'Employee List';
const header = ["S No", "Employee Name", "Age", "Image"];
/// Create workbook and worksheet
let workbook = new Workbook();
let worksheet = workbook.addWorksheet('list');
/// Header Part
let titleRow = worksheet.addRow([title]);
worksheet.mergeCells('A1:D1');
titleRow.font = { bold: true };
worksheet.addRow([]);
let headerRow = worksheet.addRow(header);
headerRow.eachCell((cell, number) => {
cell.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FFFFFF00' },
bgColor: { argb: 'FF0000FF' }
}
})
// * Data Table Starts
let employeelist = []; // Get data from backend
employeelist.forEach(async (e, i) => {
let val = [i + 1, e.name, e.age, ''];
worksheet.addRow(val);
const row = worksheet.lastRow;
row.height = 70.50;
if (e.image) {
try {
const base64Image = await Filesystem.readFile({
path: e.image,
directory: FilesystemDirectory.Data
});
let imageId = workbook.addImage({
base64: "data:image/jpeg;base64," + base64Image.data,
extension: 'jpeg',
});
var range = 'B' + (i + 2) + ':B' + (i + 2);
console.log("image id = " + imageId)
worksheet.addImage(imageId, range);
} catch (error) {
alert(error);
}
}
});
// * End Data
//Footer Row
worksheet.addRow([]);
worksheet.addRow([]);
let footerRow = worksheet.addRow(['This is system generated excel sheet.']);
worksheet.mergeCells(`A${footerRow.number}:F${footerRow.number}`);
// Export XLSX
setTimeout(async () => {
try {
const buffer = await workbook.xlsx.writeBuffer();
var encodedBytes = Buffer.from(buffer).toString('base64');
var base64 = 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' + encodedBytes;
const r = await Filesystem
.writeFile({
path: projects.projectname + ".xlsx",
data: base64,
directory: FilesystemDirectory.Documents,
}).then((writeFileResult) => {
Filesystem.getUri({
directory: FilesystemDirectory.Documents,
path: projects.projectname + ".xlsx"
}).then((getUriResult) => {
const path = getUriResult.uri;
this.fileOpener.open(path, 'application/pdf')
.then(() => console.log('File is opened'))
.catch(error => console.log('Error openening file', error));
}, (error) => {
console.log(error);
});
console.log("Downloaded Successfully!");
});
} catch (error) {
alert(error);
console.error('Unable to write file', error);
}
}, 8000);
}
}
Enjoy your code! Have a great day!