为什么在用 spatie/browsershot 生成的 pdf 文件中没有标题并且任何页面的最后一行都被切断?

如何解决为什么在用 spatie/browsershot 生成的 pdf 文件中没有标题并且任何页面的最后一行都被切断?

在 Laravel 8 应用程序中,我使用 browsershot 制作了 pdf 文件,它对我来说基本正常,除了 如果我的数据包含多个页面我有两个问题:

  1. 我没有看到我用页脚定义的页眉(下面的代码):https://imgur.com/a/2bkn3aD

  2. 我看到任何页面的最后一行都被截断了:https://imgur.com/a/cKpv7yR

我使用传递到控件 html 内容生成文件名的代码来实现:

        $filename_to_save = $option_output_filename . '.' . $option_output_file_format;
        $save_to_file     = 'generate_profile_card_' . Session::getId() . '_' . $filename_to_save;

        $today_date = getCFFormattedDate(Carbon::Now(config('app.timezone')));
        $site_name  = config('app.name','');

        $footerHtml = '<div class="card-text d1" style="background-color: #ffffff !important; width: 100%; margin : 0 !important;">
            <table style="width: 100%; font-family: \'system-ui\'; font-size: 12px !important; padding : 20px 0 0 0 !important; margin: 0 !important;
                color:#101010 !important; ;" >

                <tbody>';
        $footerHtml .= '
                <tr>
                    <td style="width:100%; border:0; border-top: 8px solid #c1c1c1; padding: 0; WWmargin: 21px 32px 2px 32px !important;" colspan="3">
                        <table style="width:100%;  ">
                            <tr>
                                <td style="width:30%;" class="d-2">
                                    Printed on: ' . $today_date . '
                                </td>
                                <td style="width:30%; " >
                                    <span class="pageNumber"></span><span>out of</span><span class="totalPages"></span>
                                </td>
                                <td style="width:40%;" >
                                    ' . $site_name . '
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
';

        $footerHtml .= '            </tbody></table>
        </div>';

        if (strtolower($option_output_file_format) == 'pdf') {
            browsershot::html(htmlspecialchars_decode($this->requestData['adCardContent']))
                       ->showbrowserHeaderAndFooter()
                       ->headerHtml('<div style="height:280px !important; background : maroon !important; ">Ad Card</div>')
                       ->footerHtml($footerHtml)
                       ->showBackground()
                       ->margins(20,10,20,10)
                       ->setoption(
                           'addStyleTag',// I inject some tailwindcss classes
                           json_encode([
                               'content' => '

.d1 {
    --tw-border-opacity: 1;
    border-color: rgba(220,38,var(--tw-border-opacity));
    border-width: 2px;
}

.d2 {
    --tw-border-opacity: 1;
    border-color: rgba(245,158,11,var(--tw-border-opacity));
    border-width: 4px;
}



    h3 {
       font-size: 32px;
       padding:4px;
    }
    h4 {
       font-size: 24px;
        padding:3px;
    }

.md:h-4/6 {
    height: 66.666667%;
}

.sm:h-4/5 {
    height: 80%;
}

.text-left {
    text-align: left;
}
.shadow-lg {
    --tw-shadow: 0 10px 15px -3px rgba(0,0.1),0 4px 6px -2px rgba(0,0.05);
    Box-shadow: var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,var(--tw-shadow);
}

.p-2 {
    padding: 0.5rem;
}
.px-6 {
    padding-left: 1.5rem;
    padding-right: 1.5rem;
}
.py-4 {
    padding-top: 1rem;
    padding-bottom: 1rem;
}

.mb-5 {
    margin-bottom: 1.25rem;
}

.max-h-screen {
    max-height: 100vh;
}
.justify-between {
    justify-content: space-between;
}

.card-text {
    background : maroon !important;
    border: 4px dotted red !important;
}

.pageNumber {
    background : yellow !important;
}

.totalPages {
    background : blue !important;
}

.flex-col {
    flex-direction: column;
}
.flex {
    display: flex;
}

.modal_container {
    color: green !important;
    border-radius: 0.5rem;
    border-width: 2px;
    padding: 0.5rem;
    border: 4px dotted blue !important;
}


.overflow-y-auto {
    overflow-y: auto;
    border: 4px dotted green !important;
}


.float-left {
    float: left;
}

.big_badge {
    border-color: rgba(209,213,219,var(--tw-border-opacity));
    border-radius: 0.5rem;
    border-bottom-width: 2px;
    display: flex;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 2.25rem;
    margin: 0.5rem;
    padding: 0.75rem;
}

.mt-3 {
    margin-top: 0.75rem;
}

.pt-3 {
    padding-top: 0.75rem;
}'
                           ])
                       )
                       ->save($save_to_file);
            \Response::download(
                $save_to_file,$save_to_file,array('Content-Type: application/octet-stream','Content-Length: ' . $option_output_file_format)
            );

            return response()->download($save_to_file,$filename_to_save)->deleteFileAfterSend(true);

在 composer.json 中:

"laravel/framework": "^8.12","spatie/browsershot": "^3.40",

如何修复?

修改 我在生成 pdf 时仍然有这些问题: 我在实时服务器上上传了示例。 请打开 http://tads-back.my-demo-apps.tk/admin/ads/2/edit登录页面凭据已经填写。只需点击登录 通过上面的链接将打开模态页面,请单击“生成”按钮。 认情况下,生成的 pdf 文件会出现我在主题的打印屏幕中显示的问题。 我在 bootstrap 4.5 中使用了这个库并且没有出现这样的问题。 同样在 https://github.com/spatie/browsershot 的描述中我没有看到任何错误描述 带页脚。

我的代码我展示了如何设置顺风类

->setoption('addStyleTag'
    ...

    

也许顺风有一些我错过的渲染功能

谢谢!

解决方法

browsershot 使用 puppeteer 包。根据 puppeteer 的说法,页脚和页眉是不同的 html。因此,如果您在要保存的主页中包含了任何 css 库,如 tailwindcss 或 bootstrap,这并不意味着它们将被加载用于页脚和页眉。对于 tailwindcss,您需要确保在生产构建中包含页脚和页眉中使用的任何 css 类,因为 postcss 将消除未使用的类以减少最终构建资产。

要获得正确的定位和大小,您需要在浏览器截图中使用边距以及页脚和页眉的正确样式。例如,您需要增加此页脚的垂直边距和页脚中的字体大小:

footer.blade.html:

<style>
    * {
        box-sizing: content-box;
    }

    footer {
        width: 100%;
        border: 1px solid yellowgreen;
        display: flex;
        flex-direction: row;
    }

    footer>div {
        color: blue;
        width: 100%;
        height: 20px;
        font-size: 10rem;
        text-align: center;
    }
</style>
<footer>
    <div>
        Printed on: {{$today_date}}
    </div>
    <div>
        {{$site_name}}
    </div>
    <div>footer</div>
</footer>

然后加载页脚 html 并使用正确的边距:

    $footerHtml =  view('footer',compact(['today_date','site_name']))->render();
        Browsershot::html($content)
            ->showBrowserHeaderAndFooter()
            ->headerHtml(view('header')->render())
            ->footerHtml($footerHtml)
            ->showBackground()
//->margins(20,10,20,10) doesn't work with above footer html.
            ->margins(30,30,10)
            ->save($save_to_file);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?