How to download excel files in fastify? - fastify

This is my API response Currently, I'm using "node-excel-export" package for downloading. It is converted to excel format but the download functionality is not working. Here is my code
var specification = {
ASSIGNED_TO: {
displayName: 'ASSIGNED_TO',
width: '10',
headerStyle: { font: { bold: true } }
},
};
var fileName = 'Parent-List';
var sheetData = {
name: 'Sheet 1',
specification: specification,
data: responseData
};
var report = excel.buildExport([sheetData]);
reply.header('Content-Type', 'application/vnd.openxmlformats');
reply.header('Content-Disposition', 'attachment; filename=' + fileName + '.xlsx');
reply.send(report);

Related

Questions regarding pdf to image conversion with Node JS

The plan is to create a pdf file (that only consists of a single page) then the user chooses whether to download as PDF or image. I have already written the code for generating the PDF and it is working fine as of now. The problem now is how to convert this to image. Is it possible to convert files without installing stuff like Ghostscript etc?
I am a complete noob, advice is greatly appreciated. (Recommendations on which libraries to use would also be helpful)
Code for generating the PDF
import PDFDocument from "pdfkit";
static async medicalPrescription(req, res) {
// Some code for generating the PDF contents...
filename = encodeURIComponent(filename) + '.pdf'
res.setHeader('Content-disposition', 'attachment; filename="' + filename + '"')
res.setHeader('Content-type', 'application/pdf')
const content = req.body.content
doc.y = 300
doc.text(content, 50, 50)
doc.pipe(res)
doc.end()
}
The client then receives the generated file and opens it in another tab.
React file that sends the request and opens the response
const handleSubmit = async (e) => {
// Some code for sending the pdf content from the user
fetch("http://localhost:5050/generate-rx", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: parsed
})
.then(async res => {
if (res.status === 200) {
const blob = await res.blob();
const file = new Blob(
[blob],
{type: 'application/pdf'}
);
const fileURL = URL.createObjectURL(file);
window.open(fileURL);
}
})
}
You can use pdf2pic. It can convert pdf to image.
import { fromPath } from "pdf2pic";
const options = {
density: 100,
saveFilename: "untitled",
savePath: "./images",
format: "png",
width: 600,
height: 600
};
const storeAsImage = fromPath("/path/to/pdf/sample.pdf", options);
const pageToConvertAsImage = 1;
storeAsImage(pageToConvertAsImage).then((resolve) => {
console.log("Page 1 is now converted as image");
console.log(resolve); // send resolve to user
});

Axios Excel file download using POST results in corrupted file

I was using Axios to download a file provided by a GET endpoint previously. The endpoint has changed and is now a POST, however the parameters are not required. I'm updating the original download method, but am getting a corrupted file returned.
downloadTemplate() {
axios.post(DOWNLOAD_TEMPLATE_URL,
{
responseType: 'blob',
headers: {
'Content-Disposition': "attachment; filename=template.xlsx",
'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
}
})
.then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'template.xlsx');
document.body.appendChild(link);
link.click();
})
.catch((error) => console.log(error));
}
I'm not sure if the issue is with the responseType, headers, or how the response is handled or all of the above. I've tried various options with no luck so far. Any suggestions would be greatly appreciated!
I have been able to download the file using Postman so I know the file served by the endpoint is fine. I just can't sort out the params to do this in my React code.
Finally got it working! The post syntax in the code block for the question was not correct and also changed the responseType to "arraybuffer".
Working example below:
downloadTemplate() {
axios.post(DOWNLOAD_TEMPLATE_URL, null,
{
headers:
{
'Content-Disposition': "attachment; filename=template.xlsx",
'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
},
responseType: 'arraybuffer',
}
).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'template.xlsx');
document.body.appendChild(link);
link.click();
})
.catch((error) => console.log(error));
}
We can use the following code to export Excel files from the POST method. May it help someone and save time.
For API use .Net Core 2.2 and the method is below.
Note: When we create a FileStreamResult, Content-Disposition header for the response will contain the filename and the stream will come as an attachment.
Add the "Content-Disposition" to Cors at Startup file,
app.UseCors(b => b.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials().WithExposedHeaders("Content-Disposition"));
I am using the EPplus package for generating the Excel file.
using OfficeOpenXml;
using OfficeOpenXml.Style;
public static MemoryStream InvoiceToExcel(List<InvoiceSearchDto> invoices)
{
var listOfFieldNames = typeof(InvoiceSearchDto).GetProperties().Select(f => f.Name).ToList();
int cellCounter = 1, recordIndex = 2;
var ms = new MemoryStream();
using (ExcelPackage package = new ExcelPackage(ms))
{
ExcelWorksheet worksheet;
worksheet = package.Workbook.Worksheets.Add("New HGS");
// Setting the properties of the first row
worksheet.Row(1).Height = 20;
worksheet.Row(1).Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
worksheet.Row(1).Style.Font.Bold = true;
// Header of the Excel sheet
foreach (string header in listOfFieldNames)
{
worksheet.Cells[1, cellCounter++].Value = header;
}
// Inserting the article data into excel
// sheet by using the for each loop
// As we have values to the first row
// we will start with second row
foreach (InvoiceSearchDto invoice in invoices)
{
worksheet.Cells[recordIndex, 1].Value = invoice.CompanyName;
worksheet.Cells[recordIndex, 2].Value = invoice.CustomerNo;
worksheet.Cells[recordIndex, 3].Value = invoice.DocumentNumber;
worksheet.Cells[recordIndex, 4].Value = invoice.BillingPeriodStartDate.ToString("YYYY-MM-DD");
worksheet.Cells[recordIndex, 5].Value = invoice.BillingPeriodEndDate.ToString("YYYY-MM-DD");
worksheet.Cells[recordIndex, 6].Value = invoice.DateOfInvoice.ToString("YYYY-MM-DD");
worksheet.Cells[recordIndex, 7].Value = invoice.ExpirationDate.ToString("YYYY-MM-DD");
worksheet.Cells[recordIndex, 8].Value = invoice.Amount;
worksheet.Cells[recordIndex, 9].Value = invoice.InvoiceStatusText;
recordIndex++;
}
// By default, the column width is not
// set to auto fit for the content
// of the range, so we are using
// AutoFit() method here.
worksheet.Column(1).AutoFit();
worksheet.Column(2).AutoFit();
worksheet.Column(3).AutoFit();
worksheet.Column(4).AutoFit();
worksheet.Column(5).AutoFit();
worksheet.Column(6).AutoFit();
worksheet.Column(7).AutoFit();
worksheet.Column(8).AutoFit();
worksheet.Column(9).AutoFit();
package.Save();
}
ms.Position = 0;
return ms;
}
The Action Method code is as below
[HttpPost]
[Route("[action]")]
public IActionResult GetInvoiceWithExcel([FromBody]SearchInvoice searchInvoice)
{
try
{
if (!string.IsNullOrEmpty(searchInvoice.InvoiceDateFrom))
{
searchInvoice.DateFrom = Convert.ToDateTime(searchInvoice.InvoiceDateFrom);
}
if (!string.IsNullOrEmpty(searchInvoice.InvoiceDateTo))
{
searchInvoice.DateTo = Convert.ToDateTime(searchInvoice.InvoiceDateTo);
}
var invoices = invoiceBatchService.GetAllForExcel(searchInvoice.PagingParams, searchInvoice, searchInvoice.FilterObject);
if (invoices != null)
{
MemoryStream invoiceStream = ExcelConverter.InvoiceToExcel(invoices);
var contentType = "application/octet-stream";
var fileName = "Invoice.xlsx";
return File(invoiceStream, contentType, fileName);
}
else
{
ResponseModel.Notification = Utility.CreateNotification("Not Found Anything", Enums.NotificationType.Warning);
return NotFound(ResponseModel);
}
}
catch (Exception ex)
{
NLogger.LogError(ex, "Get Invoice With Excel");
ResponseModel.Notification = Utility.CreateNotification(Helpers.ExceptionMessage(ex), Enums.NotificationType.Error);
return StatusCode(500, ResponseModel);
}
}
Finally the React and axois code as below.
the Service code:
return http.post(
API_BASE_URL + "/Invoice/GetInvoiceWithExcel",
searchInvoice,
{
headers: getHeaders(), // for token and others
responseType: 'blob' // **don't forget to add this**
}
);
};
And the Action method Code is below. Here I use the "file-saver" package to download the file.
import { saveAs } from 'file-saver';
export const getInvoiceWithExcel = invoiceInfo => {
return dispatch => {
dispatch({
type: LOADING_ON
});
InvoiceService.getInvoiceWithExcel(invoiceInfo)
.then(res => {
console.log(res);
let filename = res.headers['content-disposition']
.split(';')
.find((n) => n.includes('filename='))
.replace('filename=', '')
.trim();
let url = window.URL
.createObjectURL(new Blob([res.data]));
saveAs(url, filename);
dispatch({
type: GET_INVOICE_EXCEL_SUCCESS,
payload: ""
});
dispatch({
type: LOADING_OFF
});
dispatch({
type: ON_NOTIFY,
payload: {
...res.data.notification
}
});
})
.catch(err => {
dispatch({
type: GET_INVOICE_EXCEL_FAILED
});
dispatch({
type: LOADING_OFF
});
dispatch({
type: ON_NOTIFY,
payload: {
...Utility.errorResponseProcess(err.response)
}
});
});
};
};

Download excel file in angular 7

Hey after struggling to download the excel from server below is the solution i found very easy.But API side they will just read the path and send the files.
How can i differentiate the file type?
If server files are in your project directory or server , we would like to down load the excel or any file directly. Added the below implementation which works only for excel.
API(.net):
public ActionResult Download()
{
string fileName = WebConfigurationManager.AppSettings["filename"];
var filePath = System.Web.HttpContext.Current.Server.MapPath("~/" + fileName);
if (System.IO.File.Exists(filePath))
{
byte[] fileBytes = System.IO.File.ReadAllBytes(filePath);
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
else
{
var response = new WebServiceStatus()
{
code = -1,
data = null,
message = "File is Not available"
};
var data = JsonConvert.SerializeObject(response);
return HandleTrivialHttpRequests(data);
}
}
Angular V7
//Declaration
headers: HttpHeaders;
options: any;
//Constructor or u can have for specific method
this.headers = new HttpHeaders({ 'Content-Type': 'application/json' });
this.options = {
observe: 'response',
headers: this.headers,
responseType: 'arraybuffer'
};
//Service request:
this.httpClient.post('http://localhost:8080/api/report', this.data,
this.option)
.pipe(
catchError(err => this.handleError(err))
).subscribe(response => {
Helper.exportExelFile(response, 'FileName');
});
//In component or in helper function in one class, I have used helper
function which can be reused in other places also
import * as FileSaver from 'file-saver';
function exportExelFile(data, filename) {
const blobValue = new Blob([data['body']], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
FileSaver.saveAs(blobValue, filename + '.' + FileType.EXCEL);
}
export const Helper = {
exportExelFile
};

How can I write a csv in a file with xslx library in node?

I have to convert one of the sheets from an xslx to csv, for that I use the following code:
url = 'routes/file.xlsx';
const workbook = XLSX.readFile(url);
const csv = XLSX.utils.sheet_to_csv(workbook.Sheets.files);
XLSX.writeFile(csv, 'file.csv');
But when I execute it, I get that error, some idea of ​​what to do.
Thank you
First of all generate your CSV content:
var table = document.getElementById(id);
var wb = XLSX.utils.table_to_book(table, { sheet: "Sheet JS" });
var ws1 = wb.Sheets[wb.SheetNames[0]];
var csv = XLSX.utils.sheet_to_csv(ws1, { strip: true });
download_file(csv, 'my_csv.csv', 'text/csv;encoding:utf-8');
And then the download_file function credit to Javascript: set filename to be downloaded:
function download_file(content, fileName, mimeType) {
var a = document.createElement('a');
mimeType = mimeType || 'application/octet-stream';
if (navigator.msSaveBlob) { // IE10
navigator.msSaveBlob(new Blob([content], {
type: mimeType
}), fileName);
} else if (URL && 'download' in a) { //html5 A[download]
a.href = URL.createObjectURL(new Blob([content], {
type: mimeType
}));
a.setAttribute('download', fileName);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
} else {
location.href = 'data:application/octet-stream,' + encodeURIComponent(content); // only this mime type is supported
}
}

How to generate excel file using node.js?

Hi I am go for the generate excel file form the array but I am not getting successes. I am work using node.js and I am use npm package for generate excel file but I am not getting any data in excel file. excel is generate but not getting any type of data in my file. so any one know where is my mistake then please let me know how can fix it.
This is my array and query =>
var XLSX = require('xlsx');
var Array = [];
Array.push({
username: 'Carakc',
fullName: 'Crack',
followingCount: 2655,
followerCount: 466,
biography: 'I am new man'
},
{
username: 'mahi',
fullName: 'Fit',
followingCount: 3011,
followerCount: 385,
biography: 'hello everyone!'
})
app.get(prefix + '/GetFollowersInExcel', function (req, res, next) {
var ws = XLSX.utils.json_to_sheet(Array);
var wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Followres");
var wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
res.end(wbout, 'binary');
}
});
}
});
})
This is my service code =>
GetFollowersInExcel: function (InstaId) {
return $http({
method: "GET",
url: ONURL + "GetFollowersInExcel",
responseType: "arraybuffer",
headers: {
'Content-type': 'application/json',
'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
}
}).then(function (data, status, xhr) {
debugger;
if (data.data.byteLength > 0) {
var file = new Blob([data.data], { type: 'application/binary' });
var fileURL = URL.createObjectURL(file);
$('#getexcel').show();
var link = document.createElement('a');
link.href = fileURL;
link.download = "myfile.xlsx";
link.click();
URL.revokeObjectURL(file);
}
}, function (error) {
return error;
})
},
using this wave I am getting like this data in excel =>
I want like this data in excel file =>
I've tried your first code and I've found no errors, the resulting xlsx is perfect.
Peheraps I've found the problem: var Array is declared outside the app.get callback... Are you sure that your var Array can be correctly reached by XLSX.utils.json_to_sheet? it's in the same scope? or it's declared somewhere inaccessible?
try to declare it inside the callback and probably all will work well, and, if this is the case, you can use a class or a method to retrieve the var from outside ("how" depends on your code)
P.s. change the name of the var, is not a good habit overwrite the Array object ;)

Resources