有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在生成的PDF中缺少图像

我试图在iText库的帮助下将HTML页面转换为PDF。我没有太多的经验,我无法将我的图片添加到PDF中

首先,我阅读了一个HTML模板(我使用它作为基础)。图像与<img>标记一起放置,如下<img src="http://clipartmag.com/image/iron-man-face-drawing-6.png" class="avatar-image">。我从该模板中检索Document类。我将想要的内容添加到Document实例中。完成后,我检索html并使用它生成PDF

String resumeFilePath = String.format(RESUME_FILE_PATH, userProfileBean.getFirstname(), userProfileBean.getLastname());
            Document resumeAsHtml = createHtmlDocument(userProfileBean);
            HtmlConverter.convertToPdf(resumeAsHtml.html(), new FileOutputStream(resumeFilePath));
            File newResume = new File(resumeFilePath);

在测试阶段,我甚至单独创建了HTML页面,以查看一切是否就绪。网页中有该图像。但当我打电话时

HtmlConverter.convertToPdf(
    resumeAsHtml.html(), new FileOutputStream(resumeFilePath));

创建的PDF缺少图像。我在日志中还发现了3个错误:

2019-09-29 10:06:22,678 ERROR c.i.s.c.p.s.CssParserStateController:495 - The rule @keyframes is unsupported. All selectors in this rule will be ignored.
2019-09-29 10:06:22,944 ERROR c.i.s.r.r.ResourceResolver:146 - Unable to retrieve image with given base URI (file:/Users/jklancic/dev/custom/resume/) and image source path (http://clipartmag.com/image/iron-man-face-drawing-6.png)
2019-09-29 10:06:22,947 ERROR c.i.h.a.i.DefaultHtmlProcessor:356 - Worker of type com.itextpdf.html2pdf.attach.impl.tags.DivTagWorker unable to process com.itextpdf.html2pdf.attach.impl.tags.ImgTagWorker

你知道怎么回事吗?以下是已包含图像的模板:

<!DOCTYPE html>
<html>
<head>
<style>

#resume-header {
    margin-bottom: 25px;
}

#resume-body {
}

#clear {
    clear: both;
}

.header-left {
    width: 29%;
    height: 160px;
    float: left;
}

.header-right {
    padding-top: 10px;
    width: 70%;
    height: 160px;
    float: right;
}

.header-right h1,h2,h3 {
    text-align: left;
    font-family: verdana;
}

.header-right h1 {
    color: #4065a3;
    font-size: 34px;
    margin: 5px 0px 15px 0px;
}

.header-right h2 {
    font-size: 22px;
    margin: 5px 0px 5px 0px;
}

.header-right h3 {
    font-size: 10px
}

.avatar-image {
    display: block;
    margin-left: auto;
    margin-right: auto;
    height: 160px;
}

.info {
    margin: 0px 20px 0px 0px;
    font-family: verdana;
    font-size: 10px
}

span.section-header {
    color: #507fcc;
    font-family: verdana;
    font-size: 16px;
    margin: 0px 0px 0px 10px;
}

p.section-title {
    color: #000000;
    font-family: verdana;
    font-size: 12px;
}

p.section-subtitle {
    color: #9aa3b3;
    font-family: verdana;
    font-size: 12px;
    margin-left: 10px;
}

p.text {
    color: #000000;
    font-family: verdana;
    font-size: 10px;
}

ul.list {
    color: #000000;
    font-family: verdana;
    font-size: 10px;
    padding-left: 25px
}

div.web-profile {
    margin-top: 10px;
}

div.section-content {
    margin-bottom: 20px;
}

div.bottom-border {
    border-bottom: 1px solid #507fcc;
}

.primary {
    color: #507fcc;
}

.small-top-margin {
    margin: 2px 0px 0px 0px;
}

.small-bottom-margin {
    margin: 15px 0px 2px 0px;
}

</style>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css">

</head>
<body>

<div id="resume-header">
    <div class="header-left">
        <img src="http://clipartmag.com/image/iron-man-face-drawing-6.png" class="avatar-image">
    </div>
    <div class="header-right" id="basic-info">
    </div>
    <div id="clear"></div>
</div>
<div id="resume-body">
    <div class="bottom-border" id="education-section">
        <i class="fas fa-graduation-cap primary"></i><span class="section-header">Education</span>
    </div>

    <div class="bottom-border" id="job-section">
        <i class="fas fa-briefcase primary"></i><span class="section-header">Work</span>
    </div>

    <div class="bottom-border" id="skill-section">
        <i class="fas fa-pencil-ruler primary"></i><span class="section-header">Skills</span>
    </div>

</div>

</body>
</html>

共 (1) 个答案

  1. # 1 楼答案

    iText有很多bug。不要评论您正在使用的版本,但资源加载程序有几个问题,必须通过重载来纠正(它不知道如何从base64加载图像,不知道如何使用302重定向加载资源,…)

    在您的特定情况下,指示的错误是:

    Unable to retrieve image with given base URI (file:/Users/jklancic/dev/custom/resume/) and image source path (http://clipartmag.com/image/iron-man-face-drawing-6.png)

    这表明iText正在尝试访问地址“file:/Users/jklancic/dev/custom/resume/http://clipartmag.com/image/iron-man-face-drawing-6.png”。在c.i.s.r.r.ResourceResolver进行调试:146以确认

    如果您能够升级到新版本,请尝试这样做,否则您应该过载资源加载程序来修复它

    请记住,您应该首先确定确切的问题(目前类似于坏基+路径组合问题),无论如何,我修复了许多实现自定义ITextUserAgent的相关问题,如下所示:

    final ITextRenderer renderer = new ITextRenderer();
    {
        final TextUserAgent userAgent = new TextUserAgent(renderer.getOutputDevice());
        renderer.getSharedContext().setUserAgentCallback(userAgent);
        userAgent.setSharedContext(renderer.getSharedContext());
    }
    

    您必须实现自定义TextUserAgent来解决特定问题(iText现在不免费):

    public class TextUserAgent extends ITextUserAgent {
    
        public TextUserAgent(ITextOutputDevice outputDevice) {
            super(outputDevice);
        }
    
        @Override
        public ImageResource getImageResource(final String uri) {
            final ImageResource legacy = super.getImageResource(uri);
            if (legacy != null && legacy.getImage() != null) {
                return legacy;
            }
            return alternativeImageResource(uri);
        }
    ...