HTML to PDF or PNG
This commit is contained in:
commit
3a5d699c9c
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules
|
||||||
|
.vscode
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
// Olası öznitelikler hakkında bilgi edinmek için IntelliSense kullanın.
|
||||||
|
// Mevcut özniteliklerin açıklamalarını görüntülemek için üzerine gelin.
|
||||||
|
// Daha fazla bilgi için şu adresi ziyaret edin: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Debug Main Process",
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
|
||||||
|
"windows": {
|
||||||
|
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
|
||||||
|
},
|
||||||
|
"args" : ["."],
|
||||||
|
"outputCapture": "std"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,240 @@
|
||||||
|
const { app, BrowserWindow } = require('electron');
|
||||||
|
const {randomUUID} = require("node:crypto");
|
||||||
|
const { Command } = require('commander');
|
||||||
|
const express = require('express');
|
||||||
|
const multer = require('multer');
|
||||||
|
const path = require("path");
|
||||||
|
const fs = require("fs");
|
||||||
|
|
||||||
|
function writeFile(ext,data)
|
||||||
|
{
|
||||||
|
let file = randomUUID() + "." + ext;
|
||||||
|
fs.writeFileSync(
|
||||||
|
path
|
||||||
|
.resolve(
|
||||||
|
__dirname,
|
||||||
|
"./output/",
|
||||||
|
file
|
||||||
|
),
|
||||||
|
data
|
||||||
|
);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{type,website,range,background,size}} options
|
||||||
|
* @returns {Promise<[Buffer,string]>}
|
||||||
|
*/
|
||||||
|
async function generatePDF(options) {
|
||||||
|
const win = new BrowserWindow({
|
||||||
|
webPreferences:{
|
||||||
|
contextIsolation: true,
|
||||||
|
nodeIntegration: false,
|
||||||
|
disableDialogs: false,
|
||||||
|
webSecurity: true
|
||||||
|
},
|
||||||
|
show: false,
|
||||||
|
width: options.width,
|
||||||
|
height: options.height
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
await new Promise(ok => {
|
||||||
|
win.webContents.addListener("did-finish-load",()=>{
|
||||||
|
ok()
|
||||||
|
});
|
||||||
|
win.webContents.addListener("did-fail-load",()=>{
|
||||||
|
console.error("Hata oluştu")
|
||||||
|
});
|
||||||
|
|
||||||
|
if(options.htmlcontent)
|
||||||
|
{
|
||||||
|
win.loadURL(`data:text/html;base64,${Buffer.from(options.htmlcontent).toString("base64")}`);
|
||||||
|
}else{
|
||||||
|
win.loadURL(options.endpoint);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
let result = await new Promise(result => {
|
||||||
|
switch(options.type)
|
||||||
|
{
|
||||||
|
case "mhtml":{
|
||||||
|
win.webContents.savePage(path.resolve(__dirname, randomUUID() + ".mhtml"),"HTMLOnly");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "image":{
|
||||||
|
win.webContents.setZoomFactor(Math.max(0, Math.min(3.0, options.zoom)))
|
||||||
|
win.webContents.capturePage().then(e => {
|
||||||
|
let binary = e.toPNG();
|
||||||
|
result([binary, "png"]);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "pdf":{
|
||||||
|
win.webContents.printToPDF({
|
||||||
|
printBackground: true,
|
||||||
|
displayHeaderFooter: false,
|
||||||
|
scale: options.scale,
|
||||||
|
landscape: options.landscape,
|
||||||
|
pageSize: options.pageSize,
|
||||||
|
pageRanges: options.pageRanges
|
||||||
|
}).then(data => {
|
||||||
|
result([data, "pdf"]);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
win.destroy();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
app.disableDomainBlockingFor3DAPIs();
|
||||||
|
app.disableHardwareAcceleration();
|
||||||
|
|
||||||
|
app.addListener("window-all-closed",function(){
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
async function main()
|
||||||
|
{
|
||||||
|
await new Promise(ok => {
|
||||||
|
app.whenReady().then(() => {
|
||||||
|
ok()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let port = express();
|
||||||
|
|
||||||
|
|
||||||
|
port.use(express.static(path.resolve(__dirname,"./output/"),{
|
||||||
|
acceptRanges: true,
|
||||||
|
cacheControl: true,
|
||||||
|
etag: true,
|
||||||
|
lastModified: true
|
||||||
|
}))
|
||||||
|
port.use(express.static(path.resolve(__dirname,"./public/"),{
|
||||||
|
acceptRanges: true,
|
||||||
|
cacheControl: true,
|
||||||
|
etag: true,
|
||||||
|
lastModified: true
|
||||||
|
}))
|
||||||
|
|
||||||
|
port.use(function(request, response, next){
|
||||||
|
response.header("Access-Control-Allow-Origin","*");
|
||||||
|
response.header("Access-Control-Allow-Headers","*");
|
||||||
|
response.header("Access-Control-Allow-Methods","GET, POST, OPTION");
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
let memory = multer({storage: multer.memoryStorage()}).none();
|
||||||
|
|
||||||
|
port.post("/pdf", memory,async (request, response) => {
|
||||||
|
|
||||||
|
let {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
scale,
|
||||||
|
content: htmlcontent,
|
||||||
|
endpoint,
|
||||||
|
isLandscape,
|
||||||
|
pageSize,
|
||||||
|
pageRanges,
|
||||||
|
output
|
||||||
|
} = request.body;
|
||||||
|
|
||||||
|
output = output || "content";
|
||||||
|
|
||||||
|
let [content, extension] = await generatePDF({
|
||||||
|
htmlcontent,
|
||||||
|
endpoint,
|
||||||
|
type: "pdf",
|
||||||
|
landscape: isLandscape || false,
|
||||||
|
scale: scale || 1.0,
|
||||||
|
width: width || 1920,
|
||||||
|
height: height || 1080,
|
||||||
|
pageSize: pageSize || "A4",
|
||||||
|
range: pageRanges || ""
|
||||||
|
});
|
||||||
|
|
||||||
|
switch(output)
|
||||||
|
{
|
||||||
|
case "json":{
|
||||||
|
let image = writeFile(extension,content);
|
||||||
|
response.json({
|
||||||
|
status: "success",
|
||||||
|
data: image,
|
||||||
|
type: "pdf"
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "json+base64":{
|
||||||
|
response.json({
|
||||||
|
status: "success",
|
||||||
|
data: `data:application/pdf;base64,${content.toString("base64")}`,
|
||||||
|
type: "pdf"
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "content":{
|
||||||
|
response.contentType(extension);
|
||||||
|
response.end(content);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
port.post("/image", memory,async (request, response) => {
|
||||||
|
let {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
zoom,
|
||||||
|
content: htmlcontent,
|
||||||
|
endpoint,
|
||||||
|
output
|
||||||
|
} = request.body;
|
||||||
|
|
||||||
|
output = output || "content";
|
||||||
|
|
||||||
|
let [content, extension] = await generatePDF({
|
||||||
|
htmlcontent,
|
||||||
|
endpoint,
|
||||||
|
type: "image",
|
||||||
|
zoom: zoom || 1.0,
|
||||||
|
width: width || 1920,
|
||||||
|
height: height || 1080
|
||||||
|
});
|
||||||
|
|
||||||
|
switch(output)
|
||||||
|
{
|
||||||
|
case "json":{
|
||||||
|
let image = writeFile(extension,content);
|
||||||
|
response.json({
|
||||||
|
status: "success",
|
||||||
|
data: image,
|
||||||
|
type: "image"
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "json+base64":{
|
||||||
|
response.json({
|
||||||
|
status: "success",
|
||||||
|
data: `data:image/png;base64,${content.toString("base64")}`,
|
||||||
|
type: "image"
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "content":{
|
||||||
|
response.contentType(extension);
|
||||||
|
response.end(content);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
port.listen(8473);
|
||||||
|
}
|
||||||
|
process.nextTick(main);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"name": "pdfgenerator",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "main.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "electron . --inspect"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"description": "",
|
||||||
|
"dependencies": {
|
||||||
|
"commander": "^12.1.0",
|
||||||
|
"electron": "^32.1.2",
|
||||||
|
"express": "^4.21.0",
|
||||||
|
"multer": "^1.4.5-lts.1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script src="./script.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
imagé({
|
||||||
|
input: "htmlcontent",
|
||||||
|
content: "<meta charset=\"UTF-8\"><h1 style='background-color:red;color:White'>This is a PDF</h1>",
|
||||||
|
generate: "pdf",
|
||||||
|
output: "json",
|
||||||
|
success: (data)=> {
|
||||||
|
console.log(data)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
async function imagé(options)
|
||||||
|
{
|
||||||
|
if(typeof options != "object")
|
||||||
|
{
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
const {
|
||||||
|
input,
|
||||||
|
content,
|
||||||
|
endpoint,
|
||||||
|
generate,
|
||||||
|
output,
|
||||||
|
success,
|
||||||
|
...otheroptions
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
let form = new FormData();
|
||||||
|
|
||||||
|
if(input == "htmlcontent")
|
||||||
|
{
|
||||||
|
if(typeof content != "string" || !content){
|
||||||
|
throw new Error();
|
||||||
|
};
|
||||||
|
|
||||||
|
form.append("content", content)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(input == "endpoint")
|
||||||
|
{
|
||||||
|
if(typeof endpoint != "string" || !endpoint){
|
||||||
|
throw new Error();
|
||||||
|
};
|
||||||
|
|
||||||
|
form.append("endpoint", content)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(generate != "pdf" && generate == "image")
|
||||||
|
{
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(output)
|
||||||
|
{
|
||||||
|
case "json":
|
||||||
|
case "json+base64":
|
||||||
|
case "content":{
|
||||||
|
form.append("output", output);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
default:{
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const name in otheroptions) {
|
||||||
|
const value = otheroptions[name];
|
||||||
|
form.append(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
let t = await fetch("http://localhost:8473/" + generate,{
|
||||||
|
method:"post",
|
||||||
|
body: form
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!t.ok)
|
||||||
|
{
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(
|
||||||
|
t.headers.get("content-type").indexOf("application/pdf") != -1 ||
|
||||||
|
t.headers.get("content-type").indexOf("image/png") != -1
|
||||||
|
)
|
||||||
|
{
|
||||||
|
let blob = await t.blob(), file;
|
||||||
|
if(generate == "pdf")
|
||||||
|
{
|
||||||
|
file = new File([blob],"File.pdf",{
|
||||||
|
lastModified: new Date(),
|
||||||
|
type:"application/pdf"
|
||||||
|
});
|
||||||
|
}else if(generate == "image"){
|
||||||
|
file = new File([blob],"File.png",{
|
||||||
|
lastModified: new Date(),
|
||||||
|
type:"image/png"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
typeof options.success == "function" &&
|
||||||
|
options.success(file),
|
||||||
|
file
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
let data = await t.json();
|
||||||
|
return (
|
||||||
|
typeof options.success == "function" &&
|
||||||
|
options.success(data),
|
||||||
|
data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue