I am trying to create a pdf from rendered ejs file but cannot render image properly no matter how I try.
my app.js :
let express = require("express");
let app = express();
let ejs = require("ejs");
let pdf = require("html-pdf");
let path = require("path");
app.use( express.static( "public" ) );
app.get("/generateReport", (req, res) => {
ejs.renderFile("./views/report-template.ejs", (err, data) => {
if (err) {
res.send(err);
} else {
pdf.create(data).toFile("certificate.pdf", function (err, data) {
if (err) {
res.send(err);
} else {
res.send("File created successfully");
}
});
}
});
})
app.listen(3000, function(){
console.log('Server listening on port 3000');
});
----------
my report-template.ejs file
<html>
<body>
<img src="certificate.jpg" width=675 height=792>
</body>
</html>
I've saved certificated.jpg in all the locations including root,public etc..but it does'nt work..Please help ..I'm new to coding and node.
this work for me, parameter "base" in options pdf
//base: ${req.protocol}://${req.get('host')}
var options = {
"format": "A4",
"orientation": "portrait",
base: `${req.protocol}://${req.get('host')}`,
};
pdf.create(resulthtml, options).toStream(function(err, stream) {
if (err) res.end('An error occurred on create pdf');
res.setHeader('Content-disposition', 'inline; filename="' + stream.filename + '"');
res.setHeader('Content-type', 'application/pdf');
stream.pipe(res);
});
then now in template
<img src="/public/image.png">
or simply
<img src="image.png">
Related
hello this is my first post.
I'm a beginner of coding, so i watching video of opentutorials.org/course/2136/11950
i tried to find error in my code. but i can't not TT
When we enter site, it shows data lists.
[localhost:3000/topic]
enter image description here
and click the list, it shows description.
like this.
enter image description here
but in my case.. every text makes li... how can i do?
enter image description here
//app.js
const express = require('express'); //가져오기
const bodyParser = require('body-parser');//가져오기
const fs = require('fs');
const { title } = require('process');
const app = express();
app.use(bodyParser.urlencoded({extended:false})); //bodyParser를 사용하겠다.
app.locals.pretty = true;
app.set('views', './views') //템플릿엔진 위치 설정
app.set('view engine', 'pug')//어떤 엔진사용할건지 설정
app.get('/topic/new', (req, res) => res.render('new') );
app.get('/topic', (req, res) => {
fs.readdir('data',(err, data) => {
if(err){//에러가 있다면
res.status(500).send('Internal Server Error');
}
res.render('view', {topics : data}); //사용자가 topic에들어오면 글목록보이기
})
} );
app.get('/topic/:id',(req, res)=>{
const id = req.params.id;
fs.readdir('data',(err, data)=>{
if(err){
res.status(500).send('Internal Server Error');
}
})
fs.readFile('data/'+id, 'utf8', (err, data) =>{
if(err){//에러가 있다면
res.status(500).send('Internal Server Error');
}
res.render('view',{title:id, topics : data, description:data });
})
})
//바뀌는정보를 콜론+변수명
app.post('/topic',(req, res) =>
{
const title = req.body.title;
const description = req.body.description;
//파일을 쓰게하기
fs.writeFile('data/'+title, description,(err)=> { //data폴더에 title로 파일명, 내용은 description
if(err){//에러가 있다면
res.status(500).send('Internal Server Error');
}
res.send('Success!')
});
});
app.listen(3000, () => { console.log('connected 3000 port!')}) //port, 콜백(서버연결시 출력)
//view.pug
doctype html
html(lang="en")
head
meta(charset="UTF-8")
meta(http-equiv="X-UA-Compatible", content="IE=edge")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
title Document
body
h1 Server Side JavaScript
ul
each topic in topics
li
a(href="/topic/"+topic)= topic
article
h2= title
The render variable in app.get('/topic/:id') is incorrectly set. The below changes should render your view properly
app.get('/topic/:id',(req, res)=>{
const id = req.params.id;
let filesList = null
fs.readdir('data',(err, data)=>{
if(err){
res.status(500).send('Internal Server Error');
}
// This variable should be returned for topics
filesList = data
})
fs.readFile('data/'+id, 'utf8', (err, data) =>{
if(err){//에러가 있다면
res.status(500).send('Internal Server Error');
}
// Update the topics variable
res.render('view',{title:id, topics : filesList, description:data });
})
})
I,m using mutler to upload a image and i am constantly getting this error.
And i think the following function triggers it.
The complete js code is attached below.Thanks in advance!
const upload = multer({
dest: "/uploads"
});
app.post(
"/game",
upload.single("file" /* name attribute of <file> element in your form */),
(req, res) => {
const tempPath = req.file.Path;
const targetPath = path.join(__dirname, "/uploads/"+imgname+".jpg");
imgname++;
if (path.extname(req.file.originalname).toLowerCase() === ".jpg") {
fs.rename(tempPath, targetPath, err => {
if (err) return handleError(err, res);
res
.status(200)
.sendFile(__dirname + '/game.html');
});
} else {
fs.unlink(tempPath, err => {
if (err) return handleError(err, res);
res
.status(403)
.contentType("text/plain")
.end("Only .jpg files are allowed!");
});
}
}
);
Js file link: https://filebin.net/fd7q89ji16xftst4
Your code doesn't have a variable called imgname. After checking the code, it looks like you need to pass the file name for the imgname. You can use req.file.filename to get the name of the uploaded file.
Full code:
const upload = multer({
dest: "/uploads"
});
app.post(
"/game",
upload.single("file" /* name attribute of <file> element in your form */),
(req, res) => {
const tempPath = req.file.Path;
const imgname = req.file.filename;
const targetPath = path.join(__dirname, "/uploads/"+imgname);
imgname++;
if (path.extname(req.file.originalname).toLowerCase() === ".jpg") {
fs.rename(tempPath, targetPath, err => {
if (err) return handleError(err, res);
res
.status(200)
.sendFile(__dirname + '/game.html');
});
} else {
fs.unlink(tempPath, err => {
if (err) return handleError(err, res);
res
.status(403)
.contentType("text/plain")
.end("Only .jpg files are allowed!");
});
}
}
);
I am trying to build a web app that allows a user to press a button and translate a piece of text using the Bing translator api. I try to run a translator.js file through a script tag but I of course cannot run this node.js code through the client html page. What would be the proper way to design this app. Is my only choice to use something such as requirejs? I also have an app.js file built using express from which I run the app. Sorry for posting a lot of code, I want to give people an idea of the structure of my app. My experience is limited so I am feeling somewhat lost as to how to approach the design of this portion of the app. I don't expect anyone to write the code for me, but to just point in a direction of techniques that I could research so that I could build this properly.
Here is my Node.js translation request called translator.js
const request = require('request');
const uuidv4 = require('uuid/v4');
var key_var = 'TRANSLATOR_TEXT_SUBSCRIPTION_KEY';
if (!process.env[key_var]) {
throw new Error('Please set/export the following environment variable: ' + key_var);
}
var subscriptionKey = process.env[key_var];
var endpoint_var = 'TRANSLATOR_TEXT_ENDPOINT';
if (!process.env[endpoint_var]) {
throw new Error('Please set/export the following environment variable: ' + endpoint_var);
}
var endpoint = process.env[endpoint_var];
let options = {
method: 'POST',
baseUrl: endpoint,
url: 'translate',
qs: {
'api-version': '3.0',
'to': ['en']
},
headers: {
'Ocp-Apim-Subscription-Key': subscriptionKey,
'Content-type': 'application/json',
'X-ClientTraceId': uuidv4().toString()
},
body: [{
'text': 'hallo welt'
}],
json: true,
};
function displayBingTranslate() {
request(options, function(err, res, body){
document.querySelector("#bingTranslateOutput") = JSON.stringify(body, null, 4);
});
};
var accessBingTranslate = document.getElementById("accessBingTranslateButton");
accessBingTranslate.addEventListener("click", function() {
displayBingTranslate();
});
And here is my html
<!-- Section to view online translation -->
<div class="container">
<div class="row">
<div class="col-lg-12 p-0">
<button
class="btn btn-outline-dark btn-sm mb-1"
id = "accessBingTranslateButton">Translate Flashcard</button>
<div class="row m-0 p-0">
<div id="bingTranslateOutput" class="col-lg-12 m-0">
</div>
<script>
// Overall list of flashcards.
var flashcardList = {
flashcards: [],
// Adds a flashcard object to Flashcard array.
addFlashcard: function(fcTextQuestion, fcTextTranslated) {
this.flashcards.push({
fcTextQuestion: fcTextQuestion,
fcTextTranslated: fcTextTranslated
});
},
};
// Add flashcards on load.
var flashcardsDB = <%- JSON.stringify(flashcardsDB) %>;
console.log("the DB:", flashcardsDB);
flashcardsDB.forEach(function(fcardDbToAdd){
flashcardList.addFlashcard(fcardDbToAdd.question, fcardDbToAdd.translation);
});
document.querySelector("#displayFlashcardTotal").textContent = flashcardList.flashcards.length;
console.log("the rest:",flashcardList.flashcards);
var currentFlashcard = 0;
</script>
<script src="/scripts/translator.js"></script>
</body>
</html>
and here is my app.js
var express = require("express");
var app = express();
var bodyParser = require("body-parser");
var mongoose = require("mongoose");
var methodOverride = require("method-override");
// Fix mongoose deprecations
mongoose.set('useNewUrlParser', true);
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
mongoose.set('useUnifiedTopology', true);
// Connect to database.
var url = "///////";
mongoose.connect(url, {
useNewUrlParser: true,
useCreateIndex: true,
}).then(() => {
console.log("connected to mongoDB");
}).catch(err => {
console.log("Error:", err.message);
});
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static(__dirname + '/public'));
// Set 'views' directory for any views
// being rendered res.render()
app.set("view engine", "ejs");
// Override HTTP verbs if necessary.
app.use(methodOverride("_method"));
var flashcardSchema = new mongoose.Schema ({
question: String,
translation: String
});
//creates model with above schema and has methods such as .find etc.
var Flashcard = mongoose.model("Flashcard", flashcardSchema);
app.get('/', (req, res) => {
Flashcard.find({}, function(err, allFlashcards){
if(err){
console.log(err);
} else {
res.render("home", {flashcardsDB: allFlashcards});
}
});
});
// Post to an input action
app.post("/flashcards", function(req, res) {
var question = req.body.question;
var translation = req.body.translation;
var newFlashcard = {question: question, translation: translation};
console.log(newFlashcard);
Flashcard.create(newFlashcard, function(err, newlyCreated){
if(err){
console.log(err);
} else {
res.redirect("/flashcards");
}
});
});
// Show info.
app.get("/info",function (req, res) {
res.render("info");
});
// Show all flashcards
app.get("/flashcards", function(req, res){
Flashcard.find({}, function(err, allFlashcards){
if(err){
console.log(err);
} else {
res.render("flashcards", {flashcards: allFlashcards});
}
});
});
// Show form to create new campground
app.get("/new", function(req, res){
res.render("new");
});
// Edit flashcard
app.get("/flashcards/:id/edit", function(req, res){
Flashcard.findById(req.params.id, function(err, selectedFlashcard){
if(err){
req.flash("error", "Flashcard not found!");
} else {
res.render("edit", {flashcard: selectedFlashcard});
}
});
});
// Update flashcard
app.put("/flashcards/:id", function(req, res){
Flashcard.findByIdAndUpdate(req.params.id, req.body.flashcard, function(err, updatedFlashcard){
if(err){
res.redirect("/flashcards");
} else {
res.redirect("/flashcards");
}
});
});
// Destroy Flashcard
app.delete("/flashcards/:id", function(req, res){
Flashcard.findByIdAndRemove(req.params.id, function(err){
if(err){
res.redirect("back");
} else {
//req.flash("success", "flashcard deleted.");
res.redirect("/flashcards");
}
});
});
app.listen(3000, () => console.log("Flashcard app is listening"));
I think the best aproach would be to pass the translator.js to the node.js server. Create a route on express for translations, and through that route you will call the translator.js and return the result. Then, on your html page, instead of running the translator.js directly, send a request to your server passing the necessary data.
On your app.js, you can do a route like this:
const translator = require('path_to_translator');
app.get('/translation', translator);
And then on your translator.js, you can export a function that will receive the parameters you need and return the result:
const bingTranslate = (req, res) => {
// YOUR CODE HERE
}
module.exports = bingTranslate
And then on your html you will make the button send a request to your server instead of calling translator.js, so you can change the value of the #bingTranslateOutput button based on the response you will receive from the server.
I have a child process that is being called as follows:
server.js
app.get('/search', function (req, res) {
var cp = spawn('node', 'app.js');
cp.stdout.on('data', function(data) {
console.log('stdout: ' + data);
});
...
});
Currently app.js is utilizing chrome-headless' captureScreenshot function to generate a screenshot, which is then stored locally.
app.js:
const img = await Page.captureScreenshot({format: 'png', fromSurface: true});
fs.writeFile('./screenshot.png', img.data, 'base64', function (err) {
if (err) {
console.log(err);
}
});
It is not necessary to store the image locally, but rather upload it to a server. I am trying to find a way to get this functionality to work:
server.js V2
app.get('/search', function (req, res) {
var cp = spawn('node', 'app.js');
cp.stdout.on('data', function(data) {
upload_image(data);
});
...
});
app.js V2
const img = await Page.captureScreenshot({format: 'png', fromSurface: true});
//EXPOSE 'img' to parent via cp.stdout - How do I do this part?
});
You can send messages via fork()
server.js
const { fork } = require('child_process');
app.get('/search', function (req, res) {
const forked = fork('app.js');
forked.on('message', (data) => {
uploadImage(data.imageURL); // It will be send by parent.
}); ...
});
app.js
const img = await Page.captureScreenshot({format: 'png', fromSurface: true});
fs.writeFile('./screenshot.png', img.data, 'base64', function (err) {
if (err) {
console.log(err);
}
process.send({ imageURL: './screenshot.png' }); //You can send any data from here.
});
Here is the nice tutorial for you.
https://medium.freecodecamp.org/node-js-child-processes-everything-you-need-to-know-e69498fe970a
I hope it helped you.
I have been able to successfully upload images to mongoDB using GridFs.
Below are images from my database:
fs.files:
fs.chunks:
Below is the code I used to upload images:
var Grid = require('gridfs-stream');
var mongoose = require("mongoose");
Grid.mongo = mongoose.mongo;
var gfs = new Grid(mongoose.connection.db);
app.post('/picture', function(req, res) {
var part = req.files.filefield;
var writeStream = gfs.createWriteStream({
filename: part.name,
mode: 'w',
content_type:part.mimetype
});
writeStream.on('close', function() {
return res.status(200).send({
message: 'Success'
});
});
writeStream.write(part.name);
writeStream.end();
});
The Issue:
I can't seem to figure out how to read this image from mongoDB and display it on the front end in a HTML <img> tag.
I have tried this so far but it only displays the name of the file:
app.get('/picture', function(req, res) {
gfs.files.find({ filename: 'trooper.jpeg' }).toArray(function (err, files) {
if(files.length===0){
return res.status(400).send({
message: 'File not found'
});
}
res.writeHead(200, {'Content-Type': files[0].contentType});
var readstream = gfs.createReadStream({
filename: files[0].filename
});
readstream.on('data', function(chunk) {
res.write(chunk);
});
readstream.on('end', function() {
res.end();
});
readstream.on('error', function (err) {
console.log('An error occurred!', err);
throw err;
});
});
});
I have taken the code above from here
Can anyone please help. Ive been stuck on this for DAYS!!!!
It should really be
writeStream.write(part.data);
not
writeStream.write(part.name);