I am attempting to convert a HTML file to PDF using Puppeteer and I want to save the converted PDF file absolutely to the root. (I am using MacOS btw).
我正在尝试使用Puppeteer将一个HTML文件转换为PDF,我想将转换后的PDF文件绝对保存到根目录。(我正在使用MacOS btw)。
export const HTML_PATH = path.resolve(
"/Users/me/dev/script/src/template/index.html",
);
This is the current method I am using to achieve this. Doing this gives me an error:
这就是我目前使用的方法来实现这一点。这样做会给我一个错误:
[Error: ENOENT: no such file or directory, open 'file://Users/me/TestDirectory/RandomName.pdf']
[错误:环境:没有这样的文件或目录,请打开‘file://Users/me/TestDirectory/RandomName.pdf’]
private async convertHtmlToPdf(config: Config, name: string) {
const browser = await puppeteer.launch({
headless: "new",
});
const page = await browser.newPage();
await page.setContent(fs.readFileSync(HTML_PATH, "utf-8"), {
waitUntil: "domcontentloaded",
});
await page.emulateMediaType("screen");
const pdf = await page.pdf({
format: "A4",
path: `file://Users/me/TestDirectory/${name}-${Math.round(
Math.random() * 50,
)}.pdf`,
printBackground: true,
});
await browser.close();
}
I have already tried:
path: /Users/me/TestDirectory/${name}.pdf
我已经尝试了:路径:/USERS/Me/TestDirectory/${name}.pdf
path: ~/TestDirectory/${name}.pdf
路径:~/TestDirectory/${name}.pdf
path: file://Users/me/TestDirectory/${name}.pdf
路径:file://Users/me/TestDirectory/${name}.pdf
更多回答
don't use the file scheme when saving.
保存时不使用文件方案。
I have already tried without as well. Still doesn't work
我也已经试过了。仍然不起作用
EDIT with Symbolic Link Example
Example:
PDF Absolute path: /Users/me/TestDirectory/pdfs
PDF绝对路径:/USERS/Me/TestDirectory/pdf
Project Save Folder: /Users/me/Projects/puppeteer-project/pdfs
项目保存文件夹:/USERS/Me/Projects/puppeteer-project/pdf
Create a symbolic link (using both absolute paths):
ln -s /Users/me/Projects/puppeteer-project/pdfs /Users/me/TestDirectory
Save into Project Save Folder with relative path:
const pdf = await page.pdf({
format: "A4",
path: `pdfs/${name}-${Math.round(
Math.random() * 50,
)}.pdf`,
printBackground: true,
});
If symbolic linking isn't an option in your project, one last thing I could suggest is creating a script that runs after Puppeteer to just manually move (mv
) or copy (cp -R
) the files after they are saved. Hope this helps, good luck.
如果您的项目中没有符号链接选项,我建议的最后一件事是创建一个在Puppeteer之后运行的脚本,以便在文件保存后手动移动(Mv)或复制(cp-R)文件。希望这能帮上忙,祝你好运。
So I am able to replicate that same error when I try to use an absolute path when saving an image as well (used both macOS & Ubuntu). I think this is most likely intended to protect system files. However, I think there is another solution that may accomplish your task, but doesn't use an absolute path. The answer to your question is that saving with an absolute path isn't a good idea or requires very specific permissions/environment settings.
因此,当我尝试在保存图像时使用绝对路径(同时使用MacOS和Ubuntu)时,我能够复制相同的错误。我认为这很可能是为了保护系统文件。然而,我认为有另一种解决方案可以完成您的任务,但不使用绝对路径。您的问题的答案是,使用绝对路径保存不是一个好主意,或者需要非常具体的权限/环境设置。
const pdf = await page.pdf({
format: "A4",
path: `../${name}-${Math.round(
Math.random() * 50,
)}.pdf`,
printBackground: true,
});
Instead of the absolute path, you could instead use a relative path that uses the ../
syntax to travel into the previous directory, or a symbolic link. Below is a snippet of my file pdfs.js
code to take PDF of a webpage.
您可以使用使用../语法的相对路径或符号链接,而不是绝对路径。以下是我的文件pdfs.js代码片段,用于获取网页的PDF。
To run the code below, use this command:
node pdf.js https://example.com
要运行以下代码,请使用以下命令:node pdf.js https://example.com
const puppeteer = require('puppeteer');
const url = process.argv[2];
if (!url) {
throw "Please provide URL as a first argument";
}
async function run () {
const formattedTime = getFormattedTime();
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({width: 1920, height: 1080});
await page.goto(url);
await page.pdf({
format: "A4",
path: `pdfs/pdf-download-${formattedTime}.pdf`,
printBackground: true,
});
browser.close();
}
run();
function getFormattedTime() {
var today = new Date();
var y = today.getFullYear();
// JavaScript months are 0-based.
var m = today.getMonth() + 1;
var d = today.getDate();
var h = today.getHours();
var mi = today.getMinutes();
var s = today.getSeconds();
return y + "-" + m + "-" + d + "-" + h + "-" + mi + "-" + s;
}
There may also be another option to save outside of the project directory with sym links, but that is outside of this question scope.
Let me know if that helps out or not, good luck!
还可以使用sym链接在项目目录之外保存另一个选项,但这超出了本问题的范围。让我知道这是否有帮助,祝你好运!
So I have found a workaround, which allows me to use absolute paths which may start with ~
.
因此,我找到了一种解决方法,它允许我使用可能以~开头的绝对路径。
const expandedPath = config.invoice_dir_path.replace(
/^~($|\/|\\)/,
`${os.homedir()}$1`,
);
const pdf = await page.pdf({
format: "A4",
path: path.join(expandedPath, `${name}.pdf`),
printBackground: true,
});
更多回答
I am using this app as part of a CLI, where I am using a config file to ask the user where to save this data. Therefore, I would need to use the exact path that they provide to achieve saving a file in that directory.
我正在使用这款应用程序作为CLI的一部分,在CLI中,我使用一个配置文件来询问用户将该数据保存在哪里。因此,我需要使用他们提供的确切路径来实现在该目录中保存文件。
@Codex Cool that makes sense then, well I updated this answer with the symbolic link way, just in case you haven't tried that. So hopefully this helps!
@Codex Cool这是有道理的,我用符号链接的方式更新了这个答案,以防万一你还没有尝试过。希望这能有所帮助!
The code you have provided takes a screenshot of a web page. What I'm doing is manually changing a HTML file and once that HTML file is changed, by using query selectors, then I want to convert the HTML file to PDF and save that PDF in the directory specified by the user.
您提供的代码会截取网页的屏幕截图。我要做的是手动更改一个HTML文件,一旦更改了该HTML文件,使用查询选择器,然后我希望将该HTML文件转换为PDF,并将该PDF保存在用户指定的目录中。
Yes, it's just an example of how it works. Saving a screenshot and PDF are both very similar. One uses page.screenshot()
, one uses page.pdf()
. I included the code directly taken from your question at the top of my answer.
是的,这只是它如何工作的一个例子。保存屏幕截图和保存PDF都非常相似。一种使用page.creenshot(),另一种使用page.pdf()。我把直接取自你的问题的代码放在了我的答案的顶部。
Updated so you can try to copy and paste that if you want
已更新,因此如果需要,您可以尝试复制和粘贴
我是一名优秀的程序员,十分优秀!