marcbachmann / node-html-pdf

This repo isn't maintained anymore as phantomjs got dreprecated a long time ago. Please migrate to headless chrome/puppeteer.
MIT License
3.56k stars 545 forks source link

image is not displayed after generating the pdf ? #44

Open bgobi1991 opened 9 years ago

bgobi1991 commented 9 years ago

Is possible add css and image file path ?

marcbachmann commented 9 years ago

Currently not in the header using the options.header variable. You have to use <div id="pageHeader"></div>

But in the body it should work. There are some open issues. Please read through them if you don't figure it out by yourself. Please report back if you find your solution. I'll need to update the documentation with a bit more informations.

bgobi1991 commented 9 years ago

Sorry , i didn't understood your statement , i have attached my code below, can you give some solution ?

var html = '

'; var options = { filename: './businesscard.pdf', format: 'Letter', width: '210mm', height: '297mm', border: '10mm', timeout: 120000 }; pdf.create(html, options, function(err, buffer) { if (err) return console.log(err); console.log("Converted successfully."); });

agnivade commented 9 years ago

Hi,

I am also having the same problem. I am not using the options.header variable. Its just a simple image in the body which is loaded locally. The generated pdf just shows an empty white box.

This is the html that I am trying to print. I have verified that the image exists and has the proper permissions.

<html>
<head></head>
<body>
    <div id="contact_us">
      <div id="talk_text">Talk to us:</div>
      <div id="icons">
        <div id="mail"><img src="/home/agniva/email.png">feedback@atchayam.in</div>
      </div>
    </div>
    <div id="thank_you" class="center">Thank you! enjoy your meal!</div>
  </body>
</html>
marcbachmann commented 9 years ago

You have to use the file:// protocol for local files. I believe file:///home/agniva/email.png works.

Sent from my iPhone

On Jul 7, 2015, at 10:45 PM, Agniva De Sarker notifications@github.com wrote:

Hi,

I am also having the same problem. I am not using the options.header variable. Its just a simple image in the body which is loaded locally. The generated pdf just shows an empty white box.

This is the html that I am trying to print. I have verified that the image exists and has the proper permissions.

Talk to us:
feedback@atchayam.in
Thank you! enjoy your meal!

— Reply to this email directly or view it on GitHub https://github.com/marcbachmann/node-html-pdf/issues/44#issuecomment-119331980 .

agnivade commented 9 years ago

Works ! Thanks.

renancarrillo commented 8 years ago

I dont know how to put this protocol in action, my code is this:

   <img src="file://imagen.jpg" alt="BQueen">

So when I make the pdf the image didn't show

agnivade commented 8 years ago

I am guessing you are on a linux system. So the part of 'file://' is just the prefix. If your file is in /imagen.jpg (which it should not btw), then your path should be 'file:///imagen.jpg' (Note the extra /).

marcbachmann commented 8 years ago

@agnivade thanks for the answer. The important thing is to link to the file using an absolute path. It can't be relative to your application. So it should look like file:///home/app/files/image.png

renancarrillo commented 8 years ago

Thank you @agnivade and @marcbachmann for your answers.

I was missing the extra " / " but now its working fine.

Another thing in <img src="file:///C:/home/app/files/image.jpg"/> the slashes need to be inverted like this: <img src="file:\\\C:\\home\\app\\files\\image.jpg" />

DiegOrtega commented 7 years ago

I'm in a mac and I still can't create the pdf with the images, the images are broken.

My code is: <div class="col-lg-4" align="center"> <img src="file:\\Users\DiegOrtega\Desktop\cotizador\cotizador-3m\public\img\logoleo.png" class="img-responsive center-block" alt="Artículos Innovadores Leo" title="Artículos Innovadores Leo"> </div>

Hardik21 commented 7 years ago

Still not working for me. My Code:

var pdf = require('html-pdf');
var html = fs.readFileSync('./Media/index.html', 'utf8');
var _basePath = 'file:///' + __dirname + '\\Media\\';
var options = {
    format: 'A4',
    base: _basePath
};

pdf.create(html, options).toFile('./Media/123.pdf', function (err, res) {
    if (err) return console.log(err);
    console.log(res); // { filename: '/app/businesscard.pdf' } 
});

HTML: <img src="logo.png" alt="Logo" />

dukakent commented 7 years ago

@DiegOrtega works for me on mac:

const options = {
  format: 'A4',
  base: 'file://' + path.resolve('./public') + '/'
};
<img class="logo" src="img/logo.png">
pawansaket commented 7 years ago

Works for me image 1.Get the path of the folder where images reside using "path.join" 2.Change the '\' backward slashes into forward slashes '/'. 3.Now use the base:"file:///"+path

image

provide src of the images just the public folder contains, as: public/images/logo.png should be img src="images/logo.png"

fh4uweb commented 7 years ago

I had the same problem. Then i try this:

$mpdf = new mPDF(); $html= "img src='http://google.de/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png' alt=''>"; $mpdf->WriteHTML($html); $mpdf->debug = true; $output = $mpdf->Output(); die(__FILE__.':'.__LINE__);

WTF... This works! Why???

The crucial line was: $mpdf->debug = true;. I put that before my $mpdf->Output(); and the pictures were back.

pratitidevelop commented 6 years ago

I also had the same problem , and it git solved using the file:// solution Thanks!!

sevenbitsAnmol commented 6 years ago

i tried file:// and File:/// but still image is not displayed in Pdf.

zeshanmusawar commented 6 years ago

<img src=\"file:///var/mobile/Containers/Data/Application/0085BA55-C65D-4714-A57B-9CCF644EE0FB/Documents/tmp.png\"> I use this Line of Code but Image not show in PDF File .

josmanaba commented 6 years ago

Inside the MPDF directory there is a subdirectory called "tmp", give write permissions to it.

granit63 commented 6 years ago

I also had the same problem. please help me. I used the https:// instead file://.

The .img-thumbnail class creates a thumbnail of the image:

<"Cinque Terre">

Vishnupriya112 commented 5 years ago

If i am include id='pageHeader' image is not visible otherwise its showing

   <div class="container"  id="pageHeader-first">

            <div class="logo">
                <img src="uploads/logo/logo.png">
            </div>
            <div class="header-title">
                <h2><%= data.insName %> Report</h2>
                <span>15 May 2018</span>
            </div>

        </div>

If I remove id="pageHeader-first"

<div class="container" >

            <div class="logo">
                <img src="uploads/logo/logo.png">
            </div>
            <div class="header-title">
                <h2><%= data.insName %> Report</h2>
                <span>15 May 2018</span>
            </div>

        </div>

Then its working But I have to include header

vikashRawat commented 5 years ago

I am facing same issue after adding id='pageHeader', image gets disappear.

Vishnupriya112 commented 5 years ago

@vikashRawat could you share me your code

Vishnupriya112 commented 5 years ago
     var imgSrc = 'file:///E:/sri/new/vishnu/phase_2/public/uploads/logo/logo.png';
        var options = { 
        'border': '0.5cm',       
        format: 'A3',
        base: 'file:///E:/sri/new/vishnu/bes/public/',
        type: "pdf",
        "header": {
        "contents": ""
        },
          "footer": {
            "height": "50mm",
            "contents": {
              default: '<footer>Page: {{page}}/<span>{{pages}}</span></div></footer>', // fallback value
            }
          }
          };
        var  html = '<div></div>';
        var result = "<div id='pageHeader'><img src='" + imgSrc + "' /></div>";
        result += result1
        result += html
        var destination = pro_root_path+'/public/uploads/inspection/output.pdf' (Here Mention Your location)
        pdf.create(result, options).toFile(destination,function(err, pdf) {
            if (err) return console.log(err);
                //  console.log("Generated");     
            });

    });

Try this one @vikashRawat You have to include base file path

AishaniPrem commented 5 years ago

I have a similar problem and I dont think the file path is an issue. I tried to using the command: xvfb-run wkhtmltopdf http://google.com google.pdf The rsults looks something like this:

google.pdf

I am working on a linux machine

vikashRawat commented 5 years ago

@Vishnupriya112 , It worked without base file path. Actual problem was image source path, After using file:///(referenced from your code) path it worked successfully.

Thank for the solution :-)

Vishnupriya112 commented 5 years ago

@vikashRawat Glad to Know

ajotves commented 5 years ago

Hi,

I got the image in the PDF though absolute path: <img src="file:\\\C:\\Projects\\logo.png" />

But when I tried it with relative path: <img src="file:\\\.\\logo.png" />

I couldn't get the image in the PDF, anyone knows what is wrong?

SerlokPK commented 5 years ago

I was working on .NET Core and reading comments I resolved it doing the following.

var PDF = Renderer.RenderHtmlAsPdf(html, "file:///" + path); PDF.SaveAs(returnedPath);

So append following string to path of folder where you store PDF files and in your html, just use folder where images are:

<img src="images/footer-image.png" />

sivagopi5072 commented 5 years ago

I have used jsPdf in angular 6 to convert div to pdf. After downloading the pdf, the image inside the div is not coming in pdf. Please anybody help me. urgent requirement

sivagopi5072 commented 5 years ago

It is taking only from src="assets/image.png" but not taking dynamic value [src]="profile?.image"

AlbertHambardzumyan commented 5 years ago

Failed to insert an image in the header using host for an image. Works fine if I use absolute path for the image. However, I need to read it from host.

Works fine:

<div id="pageHeader" class="header">
  <img src="file:///sample-path/logo.svg" alt="logo">
</div>

Image is not there:

<div id="pageHeader" class="header">
  <img src="https://sample.com/logo.svg" alt="logo">
</div>

Any idea?

schoffi92 commented 4 years ago

For me the following worked to pdf so it find the images with relative path. (on Windows platform)

var options = {
    format: "A4",
    type: "pdf",
    quality: 75,
    base: "file:///" + __dirname.replace(/\\/g, "/") + "/"
};

pdf.create(html, options).toFile("document.pdf", (err, res) => {});

The html file and the js file is in the same directory. The images definied like this in html:

<img src="./images/reference1.bmp" />
harshikaS16 commented 4 years ago

I needed a solution which would make a relative path work for the image as my html is getting generated in Angular and the pdf in Node. But, the image source would not get appended to the base url from the "options" object inspite of trying multiple solutions provided above. Finally looked up on the example provided in the html-pdf npm package and replaced the "src" attribute from the html with the path as below.

let html1 = html.replace('branding','file:\\\\\\' + require.resolve('../../assets/images/branding.png').replace(/\//g,"\\\\"));

In the html, give the image name reference which is used for replacement.

<img style="height: 18px;" src="branding">

ghost commented 4 years ago

Good!

MelanieRogoff commented 4 years ago

I'm using a Mac, and what worked for me was: <imgsrc="file:///Users/melanierogoff/Desktop/nodegeneratorHW/assets/images/blog.png"> . What I needed to do was the file:// as mentioned previously, but when I copied my absolute filepath, it didn't work, until I added the extra '/' before Users. Hope that helps!

kausett commented 4 years ago

After couple of days of trying i was able to come up with some. i was able to come up with something that works.

   let imgSrc = 'file://' + __dirname + '/public/gv-logo.png';
   imgSrc = path.normalize(imgSrc);  //Make sure you import part.

in my congig file i had

//Other configs
        "header": {
            "height": "42px",
        },
        "footer": {
            "height": "42px",
        },

i had a template file index.js where i expoted pdfTemplate in this file i passed the imgSrc as a parameter to the exported function. Note if you wanted or need to add the image to the header or footer, the config did not work well with for me so i created my header and added the pageHeader to the top element also not to set your header height in your config file as directed above.

module.exports = (imgSrc) => {
    return `
        <!doctype html>
        <html>
         <head>
            <meta charset="utf-8">
            <title>PDF Result Template</title>

         </head>
         <body style="font-size: 14px !important;">
              <img alt="logo" class="img-fluid" src="${imgSrc}" style="height: 18px;" />
         </body>
        </html>
    `;
};

in the file where i am creating the pdf i have below

pdf.create(pdfTemplate(imgSrc), config).toFile('result.pdf', (err) => {
        console.log(config.base);
        if(err) {
            return console.log('error');
        }
        res.send(Promise.resolve())
    });

this solution works for me i hope someone can make use of it also 😎

rampanwar commented 4 years ago

Many people still finding this old issue.

First it was working fine in devlopment mode as I was using the full http URL (http://localhost:3000/img/logo.png). Not only on local system, but on server too. But as soon as we configured web-server proxy and renamed the full URL to https://www.example.com/img/logo.png, it stopped working. Basically won't resolve images from http URL.

So had to setup base option as mentioned in many answers here. But it only worked after using full directory path to images. For example, on linux server we have application in default apache directory and base: file:///var/www/html/front-app/img/ worked as expected

atrvicky commented 3 years ago

Linux user here. If you're on a different machine, use appropriate path to your asset

If anyone still has an issue with the image being loaded, use the following config

const pdfOptions = {
    format: "A4", // allowed units: A3, A4, A5, Legal, Letter, Tabloid
    orientation: "portrait", // portrait or landscape
    // Rendering options
    // base: assetPath, // Base path not nedded
    localUrlAccess: true, // set this to true to enable local file access
  };
  return new Promise((resolve, reject) => {
    htmlPdf.create(html, pdfOptions).toBuffer((err, buffer) => {
      if (err) {
        reject(err);
      } else {
        resolve(buffer);
      }
    });
  });

In the html code, use this

<th class="logo-wrapper">
  <img src="file:/home/mk/Documents/tests/server/helpers/images/logo.png" class="logo-img" alt="alt-text" />
</th>
jefflam commented 3 years ago

Linux user here. If you're on a different machine, use appropriate path to your asset

If anyone still has an issue with the image being loaded, use the following config

const pdfOptions = {
    format: "A4", // allowed units: A3, A4, A5, Legal, Letter, Tabloid
    orientation: "portrait", // portrait or landscape
    // Rendering options
    // base: assetPath, // Base path not nedded
    localUrlAccess: true, // set this to true to enable local file access
  };
  return new Promise((resolve, reject) => {
    htmlPdf.create(html, pdfOptions).toBuffer((err, buffer) => {
      if (err) {
        reject(err);
      } else {
        resolve(buffer);
      }
    });
  });

In the html code, use this

<th class="logo-wrapper">
  <img src="file:/home/mk/Documents/tests/server/helpers/images/logo.png" class="logo-img" alt="alt-text" />
</th>

This worked for me! I'm on a Mac. Thanks!

EduVencovsky commented 3 years ago

If anyone is still having problems, I recommend just displaying the image with a base64 using <img src="data:image/png;base64,IMAGE_BASE_64" /> because I tried every single answer here and none worked.

Using base64 is not what I want and not the best way, but worked.

inputitalia commented 2 years ago

hi i've the same issue on my project. last 'html-pdf' version last phantomjs version

I've tryed all the options

base: 'file://' + relativePathTemplate
base: 'file://' + absolutePathTemplate
base: 'file:///' + relativePathTemplate
base: 'file:///' + absolutePathTemplate

<img src="file:///{relative path}/image.png">

<img src="file:///{absolute path}/image.png">

<img src="file:\\\{relative path}\image.png">

<img src="file:\\\{absolute path}\image.png">

<img src="file://{relative path}/image.png">

<img src="file://{absolute path}/image.png">

but i still havind not showing images in final pdf.

If i try to show the original html on the browser before to be converted in pdf, i't showing fine ... I'm really confused, there is another way to make it working on?

praveen-sk commented 2 years ago

Add a png file as baground image is not working

head body

dbuilt-body-2 dbuilt-head-2 Top Bottom Top-New

neuberoliveira commented 2 years ago

my contribution here for someone else stucked with base option, its required to have a trailing slash otherwise files wont load

work file:///path/to/my/assets/

not work file:///path/to/my/assets

josueveloper commented 2 years ago

Linux user here. If you're on a different machine, use appropriate path to your asset

If anyone still has an issue with the image being loaded, use the following config

const pdfOptions = {
    format: "A4", // allowed units: A3, A4, A5, Legal, Letter, Tabloid
    orientation: "portrait", // portrait or landscape
    // Rendering options
    // base: assetPath, // Base path not nedded
    localUrlAccess: true, // set this to true to enable local file access
  };
  return new Promise((resolve, reject) => {
    htmlPdf.create(html, pdfOptions).toBuffer((err, buffer) => {
      if (err) {
        reject(err);
      } else {
        resolve(buffer);
      }
    });
  });

In the html code, use this

<th class="logo-wrapper">
  <img src="file:/home/mk/Documents/tests/server/helpers/images/logo.png" class="logo-img" alt="alt-text" />
</th>

Thanks @atrvicky, this worked for me, I only needed to add the option localUrlAccess: true, and for me worked both file:///path and file:/path. I'm using linux (ubuntu).

This is my JS code:

const pdf = require("html-pdf");
const fs = require("fs/promises");

async function readFile() {
  try {
    const content = await fs.readFile("./index.html", { encoding: "utf8" });
    var options = {
      format: "Letter",
      type: "pdf",
      localUrlAccess: true,
    };
    pdf.create(content, options).toFile("./html-pdf.pdf", function(err, res) {
      if (err) {
        console.log(err);
      } else {
        console.log(res);
      }
    });
  } catch (err) {
    console.log(err);
  }
}
readFile();

My html:

<!DOCTYPE html>
<html>
  <body>
    <img
      src="file:///home/sistemas/Escritorio/sistemas/Develop/POCs/poc-traslados-y-tours/pdf-generator/assets/pag1.png"
    />
  </body>
</html>
stariluz commented 5 months ago

Failed to insert an image in the header using host for an image. Works fine if I use absolute path for the image. However, I need to read it from host.

Works fine:

<div id="pageHeader" class="header">
  <img src="file:///sample-path/logo.svg" alt="logo">
</div>

Image is not there:

<div id="pageHeader" class="header">
  <img src="https://sample.com/logo.svg" alt="logo">
</div>

Any idea?

I have the same problem, could you resolve it? The image is displayed when it's not in header, but not if it's in.

<!-- This is displayed  -->
  <img src="{{RESOURCES_BASE_URL}}img/header.png" alt="Header" width="100%" />
  </div>
<!-- This is not displayed -->
  <div id="pageHeader">
    <img src="{{RESOURCES_BASE_URL}}img/header.png" alt="Header" />
  </div>

My resources url are localhost or a server, I need it working for both.

LuizBarros-Firyn commented 5 months ago

Tried literally every solution in here and it would still not work on Windows.

If anyone's still stuck as I was, you could convert the image to base64 and render the base64 instead.

const background = fs.readFileSync(path.join(__dirname, 'image.jpg')); // use whatever you need here

const backgroundBase64 = background.toString('base64'); // converting it to base64

<img src="data:image/jpeg;base64,${backgroundBase64}" alt='img' /> // using it as base64