Creating a PDF and moving it to a directory? - javascript

I am using PDFMake to create a PDF file, the body of which is dynamic. When I create the PDF it downloads to my downloads folder.
I would love for the PDF to be able to save to a directory of my choice. I have looked through the PDFMake docs and all I can see is that it gives you the option to give it a custom name. Does anyone know how I can make this happen. I don't want to just retrieve it from the folder it's in because it could possibly be in a different folder depending on the user.
Below is the code where I create the PDF:
function createPDF() {
let body = tinymce.get('elm1').getContent();
let docDefinition = {
content: body
};
console.log(body);
pdfMake.createPdf(docDefinition).download();
}

Example:
let fs = require('fs');
let PdfPrinter = require('pdfmake');
let printer = new PdfPrinter();
let docDefinition = {
content: .....
};
pdf = printer.createPdfKitDocument(docDefinition);
pdf.pipe(fs.createWriteStream('YOUR-PDFs/YOUR-PDF.pdf'));
pdf.end();

Related

Delete all files with a specific name, and * extension at Azure Blob Storage

I have a process where a client uploads a document. This document can be in the form of a PDF, JPG or PNG file only and it should be reuploaded once a year (it is an errors and omissions insurance policy).
I am saving this file in a container.
For deleting files from anywhere at the application, I have this function (Node):
deleteFromBlob = async function (account, accountKey, containerName, blobFolder, blobName) {
try {
const {
BlobServiceClient,
StorageSharedKeyCredential
} = require("#azure/storage-blob");
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
const blobServiceClient = new BlobServiceClient(
`https://${account}.blob.core.windows.net`,
sharedKeyCredential
);
const containerClient = blobServiceClient.getContainerClient(containerName);
const blockBlobClient = containerClient.getBlockBlobClient(blobFolder + '/' + blobName);
const uploadblobResponse = await blockBlobClient.deleteIfExists()
return true
}
catch(e) {
return false
}
}
And this works perfect when I know the file name and extension I want to delete, like "2448.pdf":
let deleteFile = await utils.deleteFromBlob(account, accountKey, "agents", "/eopolicies/", userData.agentid.toString() + ".pdf" )
But the problem Im facing is that the function above is to delete a file I know exists; for example, if the agent ID is 2448 and he uploads "policy.pdf" I save it as "2448.pdf" for easy file identification.
The problem Im facing is if the agent uploaded a .PNG last year. a .DOC a year before, and a .PDF now. If that's the case, I want to delete 2448.* and keep only the latest version of the document.
So I tried changing my function to
let deleteFile = await utils.deleteFromBlob(account, accountKey, "agents", "/eopolicies/", userData.agentid.toString() + ".*" )
And of course it is not working...
I tried to find a solution and all I found is one to list the content of a folder, then loop it and delete the specific file I want; but that will not work for me since there are 37,000 EO policies on that folder.
Is there a way to delete files with a specific name, and whatever extension?
Thanks.
I've never tried using a wildcard on the extension side of the file name. However, I would iterate through the files in the directory and find the one that contains the specific string you are looking for. Get it's index, and delete from there.

Questions about fs.writeFile

I want to use fs.WriteFile in my JS project. I am building an algorithm that outputs random data and I want to give the user the opportunity to save the data as a txt file. I have been able to implement fs.WriteFile in my project, but I have a couple of questions on how to proceed next as the function remains somewhat unclear.
How do I specify that I want to include the contents of various vars? Is it as simple as data = let1 + let2 + let3 and all of the data will be included?
can I add the current date and time in the .txt file name? If so, how?
How do I tell writeFile to save the contents to a .txt file and open a download blob so that people can specify their own download locations?
Thanks in advance!
I've tried looking at basic documentation but its mainly the same: a template using a simple string that saves into the same directory, which is what I don't want.
For you first question, you are correct. You can just combine different string variables into a larger string variable. See the documentation for string concatenation for more information.
For your second question, yes you can. You can get the current date and time with new Date() and turn it into a variety of formats. For file names, using mydate.toISOString() will probably be the most clean.
Here's an example of both of these in practice:
import fs from 'fs';
// Here's some data that we want to put in the file.
const name = "Bob";
const age = 43;
// Create the data we want to put in our file.
const data = name + '\n' + age;
// Let's grab the date and use it as part of our file name.
const date = new Date();
const fileName = `${date.toISOString()}.txt`;
// Call fs.writeFile to put the data in the file.
fs.writeFile(fileName, data, () => {
console.log(`Wrote data to ${fileName}.`);
});
Your third question is more complicated and probably worth a separate post. fs.writeFile can't do this for you. You'll have to come up with some mechanism for the user to enter their own file name and build off of that.
Edit:
To address your question in the comments, you might be a little confused with how NodeJS works. NodeJS runs on the server and doesn't have any way to deal with buttons or UIs by default like browser JavaScript does. It might be helpful to look at the differences between the two. So you won't be able to save it to the downloads folder on a button click.
With that said, we can save the file to the user's Downloads folder with the same script I posted above by adding the path to the Downloads folder to the beginning of the file name.
Here's the code above adjusted to do that:
import fs from 'fs';
import os from 'os'; // NEW
import path from 'path'; // NEW
const name = "Bob";
const age = 43;
const data = name + '\n' + age;
const date = new Date();
const fileName = `${date.toISOString()}.txt`;
// Get the user's home directory.
const homedir = os.homedir();
// Append the Downloads directory and fileName to the user's home directory.
const fullPath = path.join(homedir, 'Downloads', fileName);
// Use fullPath here instead of fileName.
fs.writeFile(fullPath, data, () => {
console.log(`Wrote data to ${fileName}.`);
});

Display contents of file on HTML page

I am looking for a way to display the contents of a directory on an HTML page. I have the following snippet of code:
const fs = require("fs");
let directory_name = "/example";
let filenames = fs.readdirSync(directory_name);
console.log("\nFilenames in directory:");
filenames.forEach((file) => {
console.log("File:", file);
});
This will display the contents of the file in the terminal(console) but I am looking for a way to change the "console.log("File:", file)" line into a statement to send the elements to my HTML page.
Any help would be appreciated.
Using Linux btw
Use the express.js res.send function.

Programmatically download and insert README.md with photos into HTML

I have a personal website written in AngularJS and NodeJS, and in the tech projects section I would like to embed README.md from a project on GitHub my account (the same way github.com) does it. I don't think iframe<> works for md files. So I have tried converting to HTML and PDF.
The second part of the README.md I want looks like this:
In particular, I would like to import the README.md files into my HTML. I have found two ways to do it:
Download the file, and convert to HTML.
var md_to_html = function(src, dest) {
// Get the markdown
var md = fs.readFileSync(src, "utf8");
var converter = new Remarkable();
var html = converter.render(md);
fs.writeFile(dest, html, function(err) {
if (err) {
return console.log(err);
}
console.log(dest + " was saved!");
});
}
Or Download the file, and convert to PDF.
var md_to_pdf = function(src, dest) {
fs.createReadStream(src)
.pipe(markdownpdf())
.pipe(fs.createWriteStream(dest));
}
Both work, however the photo disappears. That is because the dependencies let's say doc/img/photo.jpg does not get downloaded with the README. I have also written scripts to download the dependencies. But neither insert the photo into the README.pdf or README.html.
Has anyone done something like this? Embedded markdown in HTML with photos, or converted them to PDF or HTML with photos? If I could just import it kind of like a PDF with iframe<> that would be ideal, but if not, I will program it myself. But how?

Save HTML table data to a csv file with custom file path

I am currently writing an app using electron, and I'm trying to save the contents of a Html table to a CSV file.
I tried this, in this way:
let $ = require('jquery')
let fs = require('fs')
var dialog = require('electron').remote.dialog
$('#save-file').on('click', () => {
dialog.showSaveDialog({ filters: [{ name: 'csv', extensions: ['csv'] }]}, function (fileName) {
if(fileName === undefined){
console.log("Please give a file name!");
}else{
var value = $('#data-table').TableCSVExport({delivery:"value"})
fs.writeFile(fileName, value, function (err) {
});
}
});
})
It almost satisfy my needs, except for the data are all surrunded by "", which is not what I want.
Then I saw this. There are tons of similar ones like this, but they all download automatically once you click the button.
What I want is when the button gets clicked, it will show up a dialog box to let the user select a file path, then save the file to that position.
Also, I only need the tr(data) to be saved, so exclude the th(headings)
Is there any js library can satisfy my needs?
Appreciated for any guidance!
If you are looking to have a user pick their own file location, then the following code is an example of the showSaveDialog method using the csv-write-stream npm package. This is a code snippet and not a copy/paste fully working example. The relevant item is the file function plus dependencies:
const { dialog } = require('electron');
const fs = require('fs');
const csvWriter = require('csv-write-stream');
function saveFile(){
const folderLocation = dialog.showOpenDialog({
title:"Select Save Location",
properties: ["openDirectory"]
});
let writer = csvWriter()
writer.pipe(fs.createWriteStream(folderLocation))
writer.write({hello: "world", foo: "bar", baz: "taco"})
writer.end()
};
You should have the option either way, with showOpen or showSave, to navigate the file structure to pick a folder.
In reference to the handling of csv files, check the following npm packages:
csv-write-stream
csv
fast-csv
Another cool package for handling CSVs is handsOnTable for displaying them in your electron app with the look of an excel doc.

Categories