jsreport / jsreport-phantom-pdf

jsreport recipe which is rendering pdf from html using phantomjs
GNU Lesser General Public License v3.0
11 stars 8 forks source link

Handlebars helpers from main template not available in footer template #37

Open jakemarotta opened 4 years ago

jakemarotta commented 4 years ago

Hi,

I'm trying to use jsreport-core, jsreport-handlebars, and jsreport-phantom-pdf to render a pdf file with a footer. I'm able to use the data from the main template, but it doesn't seem recognize the same helpers in the footer. Is there something I need to put in the configuration to make that happen? Any help would be greatly appreciated.

OS: Windows 10 Node Version: v12.13.1

Dependency versions: "jsreport-assets": "^1.5.1", "jsreport-core": "^2.7.2", "jsreport-handlebars": "^2.1.0", "jsreport-html-to-xlsx": "^2.6.0", "jsreport-phantom-pdf": "^2.4.2", "jsreport-xlsx": "^2.3.0",

Here's the log output from jsreport:

info: Initializing jsreport@2.9.0 in dev mode
info: Setting dedicated-process (process based) strategy for rendering. Please visit http://jsreport.net/learn/configuration for information how to get more performance.
info: Using extension handlebars@2.1.0
info: Using extension phantom-pdf@2.5.1
info: Using extension xlsx@2.4.0
info: Using extension html-to-xlsx@2.7.0
info: html-to-xlsx detected phantom as available html engine
info: Using extension assets@1.6.0
info: Using general timeout for rendering (reportTimeout: 100000)
info: Using memory provider for template store. The saved templates will be lost after restart
info: reporter initialized
info: Starting rendering request 1 (user: null)
Error: Missing helper: "importStylesheet"
    at Object.<anonymous> (C:\[path_to_project]\node_modules\handlebars\dist\cjs\handlebars\helpers\helper-missing.js:19:13)
    at Object.wrapper (C:\[path_to_project]\node_modules\handlebars\dist\cjs\handlebars\internal\wrapHelper.js:15:19)
    at Object.eval [as main] (eval at createFunctionContext (C:\[path_to_project]\node_modules\handlebars\dist\cjs\handlebars\compiler\javascript-compiler.js:262:23), <anonymous>:11:145)
    at main (C:\[path_to_project]\node_modules\handlebars\dist\cjs\handlebars\runtime.js:208:32)
    at ret (C:\[path_to_project]\node_modules\handlebars\dist\cjs\handlebars\runtime.js:212:12)
    at ret (C:\[path_to_project]\node_modules\handlebars\dist\cjs\handlebars\compiler\compiler.js:519:21)
    at C:\[path_to_project]\util\report\dynamic.js:201:74 {
  description: undefined,
  fileName: undefined,
  lineNumber: undefined,
  endLineNumber: undefined,
  message: 'Missing helper: "importStylesheet"',
  name: 'Error',
  number: undefined
}

The jsreport initialization:

const path = require('path');
const jsreport = require('jsreport-core');

const DEFAULT_OPTIONS = {
  rootDirectory: __dirname,
  tempDirectory: path.join(__dirname, './temp'),
  templatingEngines: { 
    allowedModules: '*',
  },
  reportTimeout: 100000,
  autoTempCleanup: true
};

let core;

async function initialize(options) {
  core = jsreport(
    Object.assign(
      {},
      DEFAULT_OPTIONS,
      options
    )
  );

  // Enable supported engines
  core.use(require('jsreport-handlebars')());

  // Enable supported recipes
  core.use(require('jsreport-phantom-pdf')());
  core.use(require('jsreport-xlsx')());
  core.use(require('jsreport-html-to-xlsx')());

  // Other jsreport extensions
  core.use(require('jsreport-assets')({
    allowedFiles: '**/*.*',
    searchOnDiskIfNotFoundInStore: true,
    publicAccessEnabled: true
  }));

  return core.init();
}

The template object:

{
  "content": "[main_template]",
  "helpers": "[helpers]",
  "engine": "handlebars",
  "recipe": "phantom-pdf",
  "phantom": {
    "phantomjsVersion": "2.1.1",
    "footer": "[footer_template]",
    "footerHeight": "4.5cm",
    "margin": {
      "top": "1in",
      "right": "1in",
      "bottom": "1in",
      "left": "1in"
    }
  }
}

The main template (abridged):

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Invoice</title>
  <style>
    {{importStylesheet "invoice"}}
  </style>
</head>
<body>
  <!-- template body -->
</body>
</html>

The footer template:

<footer>
  <style>
    {{importStylesheet "invoice"}}
  </style>
  <hr />
  <p>Payment to be made in US dollars.</p>
  <p>Please contact {{phone}} with any questions.</p>
</footer>

The report's helpers file:

;(function (global) {

  const path = require('path');
  require(path.resolve(__rootDirectory, "reports/helpers/format"))(global);
  require(path.resolve(__rootDirectory, "reports/helpers/html"))(global);
  require(path.resolve(__rootDirectory, "reports/helpers/util"))(global);

})(this);

And the shared "util" helpers file being required:

module.exports = function (global) {

  const Handlebars = require("handlebars");

  function importStylesheet(name, options) {
    if (!name.endsWith(".css")) name += ".css"
    return new Handlebars.SafeString(`{#asset ${global.__rootDirectory}/reports/stylesheets/${name}}`);
  }

  Object.assign(global, {
    importStylesheet,
  });
}
deepesh4565 commented 1 year ago

import cv2 import sys

cascPath = sys.argv[1] faceCascade = cv2.CascadeClassifier(cascPath)

video_capture = cv2.VideoCapture(0)

while True:

Capture frame-by-frame

ret, frame = video_capture.read()

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

faces = faceCascade.detectMultiScale(
    gray,
    scaleFactor=1.1,
    minNeighbors=5,
    minSize=(30, 30),
    flags=cv2.cv.CV_HAAR_SCALE_IMAGE > add > data run function 
)

# Draw a rectangle around the faces
for (x, y, w, h) in faces:
    cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

# Display the resulting frame
cv2.imshow('Video', frame)

if cv2.waitKey(1) & 0xFF == ord('q'): break 
    break

function importStylesheet(name, options) { if (!name.endsWith (".css")) name += ".css" < run > return new Handlebars.SafeString({#asset $;global.__root Directory}/reports/stylesheets/${name < add > other > }});

include function run data value select

include add ( name ) ( function ru break ) == , ( frame )

include . waitKey(1) & 0xff ( frame (x,y), value root/other frame == ord('q')

include run value select

import cv2 import sys

cascPath = sys.argv[1] faceCascade = cv2.CascadeClassifier(cascPath)

video_capture = cv2.VideoCapture(0)

while True:

Capture frame-by-frame

ret, frame = video_capture.read()

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

faces = faceCascade.detectMultiScale(
    gray,
    scaleFactor=1.1,
    minNeighbors=5,
    minSize=(30, 30),
    flags=cv2.cv.CV_HAAR_SCALE_IMAGE
)

# Draw a rectangle around the faces
for (x, y, w, h) in faces:
    cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

# Display the resulting frame
cv2.imshow('Video', frame)

if cv2.waitKey(1) & 0xFF == ord('q'):
    break

When everything is done, release the capture

video_capture.release() cv2.destroyAllWindows() ,,import cv2 import sys

cascPath = sys.argv[1] faceCascade = cv2.CascadeClassifier(cascPath) ,,video_capture = cv2.VideoCapture(0) ,,while True:

Capture frame-by-frame

ret, frame = video_capture.read()

,, # Capture frame-by-frame ret, frame = video_capture.read()

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

faces = faceCascade.detectMultiScale(
    gray,
    scaleFactor=1.1,
    minNeighbors=5,
    minSize=(30, 30),
    flags=cv2.cv.CV_HAAR_SCALE_IMAGE
)

# Draw a rectangle around the faces
for (x, y, w, h) in faces:
    cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

# Display the resulting frame
cv2.imshow('Video', frame)

,, if cv2.waitKey(1) & 0xFF == ord('q'): break ,,# When everything is done, release the capture video_capture.release() cv2.destroyAllWindows() ,import cv2 import sys

cascPath = sys.argv[1] faceCascade = cv2.CascadeClassifier(cascPath)

video_capture = cv2.VideoCapture(0)

while True:

Capture frame-by-frame

ret, frame = video_capture.read()

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

faces = faceCascade.detectMultiScale(
    gray,
    scaleFactor=1.1,
    minNeighbors=5,
    minSize=(30, 30),
    flags=cv2.cv.CV_HAAR_SCALE_IMAGE
)

# Draw a rectangle around the faces
for (x, y, w, h) in faces:
    cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

# Display the resulting frame
cv2.imshow('Video', frame)

if cv2.waitKey(1) & 0xFF == ord('q'):
    break

When everything is done, release the capture

video_capture.release() cv2.destroyAllWindows() ,,import cv2 import sys

cascPath = sys.argv[1] faceCascade = cv2.CascadeClassifier(cascPath) ,,video_capture = cv2.VideoCapture(0) ,,while True:

Capture frame-by-frame

ret, frame = video_capture.read()

,, # Capture frame-by-frame ret, frame = video_capture.read()

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

faces = faceCascade.detectMultiScale(
    gray,
    scaleFactor=1.1,
    minNeighbors=5,
    minSize=(30, 30),
    flags=cv2.cv.CV_HAAR_SCALE_IMAGE
) function run data add value select 

# Draw a rectangle around the faces
for (x, y, w, h) in faces:
    cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

# Display the resulting frame
cv2.imshow('Video', frame)

,, if cv2.waitKey(1) & 0xFF == ord('q'): break ,,# When everything is done, release the capture video_capture.release() cv2.destroyAllWindows() , function run data value select import cv2 import sys

cascPath = sys.argv[1] faceCascade = cv2.CascadeClassifier(cascPath)

video_capture = cv2.VideoCapture(0)

while True:

Capture frame-by-frame

ret, frame = video_capture.read()

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

faces = faceCascade.detectMultiScale(
    gray,
    scaleFactor=1.1,
    minNeighbors=5,
    minSize=(30, 30),
    flags=cv2.cv.CV_HAAR_SCALE_IMAGE

)

# Draw a rectangle around the faces
for (x, y, w, h) in faces:
    cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

# Display the resulting frame
cv2.imshow('Video', frame) add (video; frame) 

Image logical select data add select condition

include function or data only function

include add data select ( x+y)

include add data

if cv2.waitKey(1) & 0xFF == ord('q'):
    break

When everything is done, release the capture

video_capture.release() cv2.destroyAllWindows() ,,import cv2 import sys

cascPath = sys.argv[1] faceCascade = cv2.CascadeClassifier(cascPath) ,,video_capture = cv2.VideoCapture(0) ,,while True:

Capture frame-by-frame

ret, frame = video_capture.read()

,, # Capture frame-by-frame ret, frame = video_capture.read()

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

faces = faceCascade.detectMultiScale(
    gray,
    scaleFactor=1.1,
    minNeighbors=5,
    minSize=(30, 30),
    flags=cv2.cv.CV_HAAR_SCALE_IMAGE 
) function run data add select 

# Draw a rectangle around the faces
for (x, y, w, h) in faces:
    cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

include function run data add run value data condtion run data add

# Display the resulting frame
cv2.imshow('Video', frame)

,, if cv2.waitKey(1) & 0xFF == ord('q'): break ,,# When everything is done, release the capture video_capture.release() cv2.destroyAllWindows()

Display the resulting

include other ord( ) <

other ( ) = add = other frame ( 0 )

( x,y,)

include value num! num2

include other run value select data

include add face ( x,y,z, )

include function

include run data value select other function

include function capture

include run data value select data run condition

include function add data select other function value data

include data condition