This is the html string and i want to print it in pdfmake
let html_string = "<html><head></head><body><p>HI</p></body></html>";
//something like this
{ text: html_string,
pageBreak: 'after',
},
it should print as a html content in a part of pdfmake: how to print string containing html as it is in pdf .
Option 1. Convert the html to string before passing it to pdfmake. You can use html-to-text
.
const PdfPrinter = require("pdfmake");
const htmlToText = require('html-to-text');
let dd = {
pageSize: "A4",
pageOrientation: "portrait",
content: [
{
text: htmlToText.fromString("<p>Hello <strong>World</strong></p>", {
wordwrap: 130
}),
style: "",
}
],
}
let printer = new PdfPrinter(fonts);
let doc = printer.createPdfKitDocument(dd);
Option 2. Use html-to-pdfmake
. You will have to add jsdom if you are doing it in Nodejs side.
const PdfPrinter = require("pdfmake");
let jsdom = require("jsdom");
let { JSDOM } = jsdom;
let { window } = new JSDOM("");
const htmlToPdfmake = require("html-to-pdfmake");
let dd = {
pageSize: "A4",
pageOrientation: "portrait",
content: [
{
text: htmlToPdfmake(salesConditions.salesConditionBody, {
window: window,
}),
style: "",
}
],
}
let printer = new PdfPrinter(fonts);
let doc = printer.createPdfKitDocument(dd);
Use a html parser to get the html content you want. https://www.npmjs.com/package/node-html-parser
After that, i would write an object build function to get the correct html tag content you're looking for.
import { parse } from 'node-html-parser';
const root = parse('<ul id="list"><li>Hello World</li></ul>');
var htmlBody = root.querySelector('#list');
function getContentBuilder (htmlBody ) {
var record = {}
//Locate htmlBody childnode that you want and insert to record
return record;
}
//something like this
{ text: getContentBuilder(htmlBody) ,
pageBreak: 'after',
},
you can use HTML2PDF Js library to make pdf from html string.
check this link here
many JS libraies available in npm to create PDF from image or html.
Related
I'm trying to generate some content for an HTML source dynamically, and then convert it to an Image (JPG or PNG) for later conversion into Base64.
For prefilling the HTML I'm using VelocityJS. And then attempting to use html-to-image library to convert the formatted HTML String/Element to an Image.
But I keep getting the following error.
oops, something went wrong! TypeError: Cannot read properties of undefined (reading 'defaultView')
at px (util.ts:69:1)
at getNodeWidth (util.ts:75:1)
at getImageSize (util.ts:87:1)
at toCanvas (index.ts:32:1)
at Module.toJpeg (index.ts:83:1)
at usePaymentReceiptBuilder.js:26:1
I first tried passing the string itself to the library. Which didn't work either. Then attempted adding the string into a div, and then wrapping it with JQuery to create an element. None of these worked.
The code is as follows.
import velocityjs from 'velocityjs';
import * as htmlToImage from 'html-to-image';
import paymentReceiptHtml from '../resources/email-receipts/payment-receipt.txt';
import useBusinessInfo from "./useBusinessInfo";
import $ from 'jquery';
const usePaymentReceiptBuilder = () => {
const {businessId, businessInfo, currencySymbol} = useBusinessInfo();
const PAPER_SIZE_TWO_INCH = 384;
const printReceiptOnCloverDevice = (purchaseEntry) => {
fetch(paymentReceiptHtml)
.then((response) => response.text())
.then((paymentReceiptHtmlTextContent) => {
let receiptContent = buildReceiptContent(purchaseEntry);
let velocityContext = {
"receiptContent": receiptContent
};
let renderedString = velocityjs.render(paymentReceiptHtmlTextContent, velocityContext);
// let htmlContent = <div dangerouslySetInnerHTML={{__html: renderedString}}/>;
let htmlContent = $(renderedString)
htmlToImage.toJpeg(htmlContent)
.then(function (dataUrl) {
console.log("generateReceiptBase64String 4");
console.log(dataUrl);
})
.catch(function (error) {
console.error('oops, something went wrong!', error);
});
});
}
const buildReceiptContent = (purchaseEntry) => {
return {
businessName: businessInfo.businessName,
businessAddress: businessInfo.address,
businessWebsite: "",
businessContactNumber: businessInfo.contactNumbers.length > 1 ? businessInfo.contactNumbers[0] : "",
businessLogoUrl: "",
receiptOrderContent: purchaseEntry,
instanceMarketingUrl: "",
orderQrCodeBase64: "",
paperWidth: PAPER_SIZE_TWO_INCH
};
}
return {printReceiptOnCloverDevice}
}
export default usePaymentReceiptBuilder
What am I doing wrong? Please assist.
I'm looking to write the perfect code for translating messages formatted for WhatsApp into messages formatted for Telegram.
Whatsapp uses * and _ for bold and italic (but if you dive into it you'll discover that the parsing rules are quite elaborate): https://faq.whatsapp.com/general/chats/how-to-format-your-messages/?lang=en
Telegram uses HTML tags: https://sendpulse.com/knowledge-base/chatbot/format-text
I've used this answer to create the following code. It works but fails to convert correctly in some cases i.e. when there is a solitary *.
function whatsapp2Telegram(WAtxt) {
var TelegramText = WAtxt
const htmlFormat = [{
symbol: '*',
tag: 'b'
},
{
symbol: '_',
tag: 'i'
},
{
symbol: '~',
tag: 'pre'
},
{
symbol: '```',
tag: 'code'
},
];
htmlFormat.forEach(({
symbol,
tag
}) => {
if (!TelegramText) return;
const regex = new RegExp(`\\${symbol}([^${symbol}]*)\\${symbol}`, 'gm');
const match = TelegramText.match(regex);
if (!match) return;
match.forEach(m => {
let formatted = m;
for (let i = 0; i < 2; i++) {
formatted = formatted.replace(symbol, `<${i > 0 ? '/' : ''}${tag}>`);
}
TelegramText = TelegramText.replace(m, formatted);
});
});
return TelegramText
}
I am trying to grab some json data to display in Ui but when I iterate over it using the map method I keep getting undefined.Any help will be really appreciated.Here is a link on code sandbox https://codesandbox.io/s/late-wood-kx8w2?file=/src/App.js
This line
const [items, setItem] = useState(Object.keys(trees));
is passing the tree keys to the View function and not the actual data. I believe that you meant to pass the data. Your code passes 'name' and 'children' as {items} that then gets displayed by View.js.
The following code shows you how you can parse the tree and get the names and the values. It's incomplete, but it should give you a start on how to do the traversal.
import React, { useState } from "react";
export default function Start(){
const trees = {
name: "root",
children: [
{
name: "child1",
children: [
{ name: "child1-child1", data: "c1-c1 Hello" },
{ name: "child1-child2", data: "c1-c2 JS" }
]
},
{ name: "child2", data: "c2 World" }
]
};
const treesCopy = trees;
function Traverse(tree){
var treesCopy = tree;
var str = [];
for (var prop in treesCopy) {
console.log(prop);
if (prop=="children"){
str = str + "name: "+ prop + ",";
treesCopy = treesCopy[prop][0];
// console.log('New tree: ',treesCopy);
return str + Traverse(treesCopy);
}
str = str + "name: "+ prop +" value: " + treesCopy[prop]+",";
}
return str;
};
const str = Traverse(treesCopy);
return(
<>
{
str ? str.split(",").map(place => <p> {place} </p>)
: ""
}
</>
)
}
There is example piece of code from official website of skrape{it}. It is about extracting data from website. I'm using library version 1.0.0-alpha6
import it.skrape.core.htmlDocument
import it.skrape.selects.and
import it.skrape.selects.eachImage
import it.skrape.selects.eachText
import it.skrape.selects.html5.a
import it.skrape.selects.html5.div
import it.skrape.selects.html5.p
import it.skrape.selects.html5.span
import org.junit.jupiter.api.Test
// just some object where we will store our scraped data
data class MyExtractedData(
var httpMessage: String = "",
var userName: String = "",
var repositoryNames: List<String> = emptyList(),
var theThirdRepositoriesName: String = "",
var firstThreeHrefs: List<String> = emptyList(),
var overviewLink: String = "",
var firstThreeImageSources: List<String> = emptyList(),
var title: String = "",
var starsCount: String = ""
)
fun main() {
val extracted = skrape { // 1️⃣
url = "https://github.com/skrapeit"
extractIt<MyExtractedData> { it ->
it.httpMessage = status { message } // 2️⃣
htmlDocument { // 3️⃣
relaxed = true // 4️⃣
it.userName = ".h-card .p-nickname" { findFirst { text } } // 5️⃣
val repositories = span(".repo") { findAll { this }} // 6️⃣
println("hello world") // 7️⃣
it.repositoryNames = repositories.filter { it.text.contains("skrape") }.eachText // 8️⃣
it.theThirdRepositoriesName = span(".repo") {
2 { text } // 9️⃣
}
it.firstThreeImageSources = findAll { eachImage.map { image -> image.value } }.take(3) // 1️⃣0️⃣
it.firstThreeHrefs = findAll { eachHref }.take(3) // 1️⃣1️⃣
it.overviewLink = findAll { eachLink["Overview"] ?: "not found" } // 1️⃣2️⃣
it.title = titleText // 1️⃣3️⃣
// *️⃣
it.starsCount = div { // 1️⃣5️⃣
withClass = "pinned-item-list-item"
findFirst {
p { // 1️⃣6️⃣
findSecond {
a {
// 1️⃣7️⃣
withClass = "pinned-item-meta" and "muted-link" // 1️⃣8️⃣
withAttribute = "href" to "/skrapeit/skrape.it/stargazers" // 1️⃣9️⃣
findFirst {
ownText
}
}
}
}
}
}
}
}
}
println(extracted)
}
This piece of code simply does not compile. All possible imports had been done.
Errors:
Unresolved reference: status
Unresolved reference: message
Unresolved reference: relaxed
Function invocation 'eachText()' expected (line with 8️⃣ comment)
Expression '2' of type 'Int' cannot be invoked as a function. The function 'invoke()' is not found (line with 9️⃣ comment)
Type mismatch. Required: List. Found: List (line with 1️⃣0️⃣ comment)
And that's not all. There are lots of errors almost in every line. Where is the mistake?
Thank you!
I know I has been a while, but I was looking at the scrape{it} yesterday for the first time and face the same issue as you did.
The guys have an error on the official docs (probably it is just a way it used to work before).
To make it work, you need to change the top of the function slightly:
val extracted = skrape(HttpFetcher) { // 1️⃣
request {
url = "https://github.com/skrapeit"
}
It did a trick for me, hope will help someone as well.
I'm trying to read some test data from a local json file and output the data with correct formatting into a textarea. Right now though it just outputs [object Object]. How would I go about getting it so it outputs:
Id: theIdGoesHere
Title: theTitleGoesHere
step.service.ts The service used to call the json data
public getJson(): Observable<any>{
return this.http.get('/assets/jsonData/MyJson.json')
.map(response => response.json());
}
MyJson.json
{
"data":[
{
"id": 1,
"title":"Test1"
},
{
"id": 2,
"title":"Test2"
}
]
}
main.componenet.ts
private testVar: any;
test(){
this.stepService.getJson().subscribe(data => (this.testVar = data));
}
anothermethod(){
this.test();
this.mainStepText = this.testVar; //mainStepText binded to textarea with [(ngModel)]="mainStepText"
}
get mainStepText2() { //Rebinded this one
const text = [];
const { data } = this.testVar;
for (let item of this.testVar.data) {
Object.keys(item).forEach(key => {
text.push(key + ': ' + item[key]);
});
}
return text.join('\r\n'); // \r\n is the line break
}
You can use json pipe to format your object into a json string:
[(ngModel)]="mainStepText | json"
If you want to show a specific property of your object, you can access it in your template:
[(ngModel)]="mainStepText.data[0].title"
This will display "Test1" in your field.
You could loop through your json.data and through their keys to extract the text and values and generate the string you need for the text area.
const text = [];
for (let item of this.textVar.data) {
Object.keys(item).forEach(key => {
text.push(key + ': ' + item[key]);
});
}
return text.join('\r\n'); // \r\n is the line break
Here's the running code, I put it in app.ts: http://plnkr.co/edit/3AbQYQOW0MVBqO91X9qi?p=preview
Hope this is of help.