英文:
How to debug html2pdf.js behavior (or reproduce CSS of exported PDF)?
问题
I'll provide a translation of the text you provided:
我正在尝试使用 html2pdf.js
导出 PDF 文档,但整个 PDF 中的文本都不对齐。
这是 HTML 中文本的样子:
这是 PDF 版本:
所有图形元素都在其位置,但所有文本都向下偏移了。而且无法检查打印出的 PDF 文档的 CSS 参数。所以实际上,我对如何创建可重现的示例并使这个问题更加专注感到困惑,因为我混合了两个庞大的 CSS 文件。一个来自我尝试打印的单独的 HTML 页面,另一个 CSS 文件是 Vue.js
应用程序的全局样式。所以我认为这里可能存在多个不正确的继承,可能会破坏样式。
以下是可能有助于我理解问题根本的多个可能答案:
-
据我所知,
html2pdf.js
① 创建 DOM 元素的克隆,② 转换为 PDF,⓷ 删除克隆元素。是否有可能存储 DOM 元素并防止删除它以便能够使用浏览器开发工具检查样式? -
正如我之前所说,所有元素的对齐都是正确的。受影响的只是文本。如何重现这种行为?
例如,黑色 テスト
文本的元素是一个简单的 div
:
<div style="display: inline-block; padding-bottom: 2px; border-bottom: 4px solid #000000;">
テスト2
</div>
黑色底线是一个 border-bottom
,我找到的唯一越过边框的方法是将 line-height
更改为较低的值,但在这种情况下文本将在垂直方向上收缩。但在 PDF 中文本被偏移。如何在不更改 div
的内边距和外边距的情况下重现此行为?只有文本应该移动。
此外,将 HTML
转换为 PDF
的函数非常简单:
import html2pdf from "html2pdf.js";
...
html2pdf(this.$refs.htmlElement, {
margin: 3,
filename: "output.pdf",
image: { type: 'jpeg', quality: 0.98 },
html2canvas: {
scale: 2,
useCORS: true,
width: 1300,
allowTaint: true,
// 我试过将其设置为 true,但控制台日志为空
logging: false
},
jsPDF: {
format: 'A4',
orientation: 'landscape',
unit: 'mm'
},
enableLinks: false
});
附加信息(2023/04/18)
我们在 Vue
应用程序中使用 tailwind
作为主要的 CSS 库。从 CSS 文件中删除 @tailwind base;
(code) 后,文本位置正确打印。但我仍然无法弄清楚 tailwindcss
的哪一部分与我的样式冲突...
附加信息(2023/04/20)
我找到了破坏文本对齐的 CSS 参数:
img {
display: block;
}
如果我全局设置 display: unset;
为 img
元素,PDF 文本将正确打印。但是,如果我尝试仅使用 scoped
关键字更改当前页面的参数,PDF 将再次生成不正确。
我尝试在生成 PDF 之前删除所有图像:
window.document.querySelectorAll('img').forEach( el => {
el.remove();
});
但即使页面中没有 img
元素,文本仍然打印不正确。我无法弄清楚 img
样式如何影响没有 img
元素的页面...
英文:
I'm trying to export PDF document with html2pdf.js
and whole text of PDF is out of alignment.
Here is how text looks inside HTML:
And here is a PDF version:
All graphical elements are in place but all texts are shifted down. And here is no way to check CSS parameters for printed out PDF document. So, actually, I'm pretty confusing how to create reproducible example and make this question more focused, because I mixed two huge CSS files. One from separated single HTML page that I'm trying to print and second CSS file is a global styles of Vue.js
application. So I think that here is multiple not correct inheritances that may break styles.
So here are multiple possible answers that should help me to understand root of problem:
-
AFAIK
html2pdf.js
① creates clone of DOM element, ② converts it to PDF, ⓷ remove cloned element. Is it possible to store DOM element and prevent deletion of it to be able check styles with browser developer tools? -
As I said before, all elements alignment is correct. Affected thing is text only. How this behavior may be reproduced?
For example element of black テスト
text is a simple div
:
<div style="display: inline-block; padding-bottom: 2px; border-bottom: 4px solid #000000;">
テスト2
</div>
Black bottom line is a border-bottom
, the only way to cross the border that I found is to change line-height
to lower value, but in this case text will be shrinked vertically. But inside PDF text is shifted. How it possible to reproduce this behavior without changing div
s paddings and margins? Only text should be moved.
Also function to convert HTML
into PDF
is pretty simple:
import html2pdf from "html2pdf.js";
...
html2pdf(this.$refs.htmlElement, {
margin: 3,
filename: "output.pdf",
image: { type: 'jpeg', quality: 0.98 },
html2canvas: {
scale: 2,
useCORS: true,
width: 1300,
allowTaint: true,
// I tried to set it to true, but console logs are empty
logging: false
},
jsPDF: {
format: 'A4',
orientation: 'landscape',
unit: 'mm'
},
enableLinks: false
});
Additional info (2023/04/18)
We are using tailwind
as main CSS library inside Vue
application. After removing @tailwind base;
(code) from CSS file text position is printing correctly. But I still can't figure out what part of tailwindcss
is conflicting with my own styles...
Additional info (2023/04/20)
I found CSS parameter that breaking text alignment:
img {
display: block;
}
If I set globally display: unset;
for img
element PDF text is printing correctly.
However, if I try to change parameter only for current page using scoped
keyword the PDF is generated not correctly again.
I tried to remove all images before generate PDF:
window.document.querySelectorAll('img').forEach( el => {
el.remove();
});
But even if here is no one img
element in page text is printing not correctly. Can't figure out how img
style may affect page without img
elements...
答案1
得分: 1
以下是翻译好的内容:
"嘿,我已经尝试根据给定的参考创建一个CodePen。并且它的输出与JavaScript代码中配置的PDF相同。
var element = document.getElementById("print");
var opt = {
margin: 1,
filename: "myfile.pdf",
image: { type: "jpeg", quality: 0.98 },
html2canvas: { scale: 2 },
jsPDF: { unit: "in", format: "letter", orientation: "portrait" }
};
html2pdf(
element,
{
margin: 3,
filename: "output.pdf",
image: { type: "jpeg", quality: 0.98 },
enableLinks: false
},
opt
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<div id="print">
<div id="print" style="display: inline-block; padding: 12px; background-color:darkgreen; color:white; font-size: .8rem">
Title
</div><br>
<div id="print" style="display: inline-block; padding-bottom: 2px; border-bottom: 4px solid #000000;">
テスト2
</div>
</div>
英文:
hey i have tried to make a codepen from given reference. And it is working fine as output of on pdf is same as configured in js code.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
var element = document.getElementById("print");
var opt = {
margin: 1,
filename: "myfile.pdf",
image: { type: "jpeg", quality: 0.98 },
html2canvas: { scale: 2 },
jsPDF: { unit: "in", format: "letter", orientation: "portrait" }
};
html2pdf(
element,
{
margin: 3,
filename: "output.pdf",
image: { type: "jpeg", quality: 0.98 },
enableLinks: false
},
opt
);
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<div id="print">
<div id="print" style="display: inline-block; padding: 12px; background-color:darkgreen; color:white; font-size: .8rem">
Title
</div><br>
<div id="print" style="display: inline-block; padding-bottom: 2px; border-bottom: 4px solid #000000;">
テスト2
</div>
</div>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论