Grails wkhtmltopdf 渲染不正确

时间:2021-06-03 13:48:16

标签: java html pdf grails wkhtmltopdf

我将使用 wkhtmltopdf 插件在 Grails 项目中将 html 转换为 pdf。

<块引用>

https://codepen.io/wizard-work/pen/oNZqXBy?editors=1000

<html>
  <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
      <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
      <title>
          Proposal
      </title>
      <meta name="viewport" content="width=device-width, initial-scale=1"/>
      <asset:link rel="icon" href="favicon.ico" type="image/x-ico"/>
      <style type="text/css">
          @page{
              size: 210mm 297mm;
          }
          body{
              background-color: #F5F5F5;
              color: #333333;
              overflow-x: hidden;
              margin: 0;

          }
          h1, h2, h3, h4, h5{
              display: block;
              font-family: "Manrope-Regular";
              margin-block-start: 1em;
              margin-block-end: 1em;
              margin-inline-start: 0px;
              margin-inline-end: 0px;
              margin: 0;
          }

          .m-0 {
            margin: 0 !important;
          }

          .mt-0,
          .my-0 {
            margin-top: 0 !important;
          }

          .mr-0,
          .mx-0 {
            margin-right: 0 !important;
          }

          .mb-0,
          .my-0 {
            margin-bottom: 0 !important;
          }

          .ml-0,
          .mx-0 {
            margin-left: 0 !important;
          }

          .m-1 {
            margin: 0.25rem !important;
          }

          .mt-1,
          .my-1 {
            margin-top: 0.25rem !important;
          }

          .mr-1,
          .mx-1 {
            margin-right: 0.25rem !important;
          }

          .mb-1,
          .my-1 {
            margin-bottom: 0.25rem !important;
          }

          .ml-1,
          .mx-1 {
            margin-left: 0.25rem !important;
          }

          .m-2 {
            margin: 0.5rem !important;
          }

          .mt-2,
          .my-2 {
            margin-top: 0.5rem !important;
          }

          .mr-2,
          .mx-2 {
            margin-right: 0.5rem !important;
          }

          .mb-2,
          .my-2 {
            margin-bottom: 0.5rem !important;
          }

          .ml-2,
          .mx-2 {
            margin-left: 0.5rem !important;
          }

          .m-3 {
            margin: 1rem !important;
          }

          .mt-3,
          .my-3 {
            margin-top: 1rem !important;
          }

          .mr-3,
          .mx-3 {
            margin-right: 1rem !important;
          }

          .mb-3,
          .my-3 {
            margin-bottom: 1rem !important;
          }

          .ml-3,
          .mx-3 {
            margin-left: 1rem !important;
          }

          .m-4 {
            margin: 1.5rem !important;
          }

          .mt-4,
          .my-4 {
            margin-top: 1.5rem !important;
          }

          .mr-4,
          .mx-4 {
            margin-right: 1.5rem !important;
          }

          .mb-4,
          .my-4 {
            margin-bottom: 1.5rem !important;
          }

          .ml-4,
          .mx-4 {
            margin-left: 1.5rem !important;
          }

          .m-5 {
            margin: 3rem !important;
          }

          .mt-5,
          .my-5 {
            margin-top: 3rem !important;
          }

          .mr-5,
          .mx-5 {
            margin-right: 3rem !important;
          }

          .mb-5,
          .my-5 {
            margin-bottom: 3rem !important;
          }

          .ml-5,
          .mx-5 {
            margin-left: 3rem !important;
          }

          .p-0 {
            padding: 0 !important;
          }

          .pt-0,
          .py-0 {
            padding-top: 0 !important;
          }

          .pr-0,
          .px-0 {
            padding-right: 0 !important;
          }

          .pb-0,
          .py-0 {
            padding-bottom: 0 !important;
          }

          .pl-0,
          .px-0 {
            padding-left: 0 !important;
          }

          .p-1 {
            padding: 0.25rem !important;
          }

          .pt-1,
          .py-1 {
            padding-top: 0.25rem !important;
          }

          .pr-1,
          .px-1 {
            padding-right: 0.25rem !important;
          }

          .pb-1,
          .py-1 {
            padding-bottom: 0.25rem !important;
          }

          .pl-1,
          .px-1 {
            padding-left: 0.25rem !important;
          }

          .p-2 {
            padding: 0.5rem !important;
          }

          .pt-2,
          .py-2 {
            padding-top: 0.5rem !important;
          }

          .pr-2,
          .px-2 {
            padding-right: 0.5rem !important;
          }

          .pb-2,
          .py-2 {
            padding-bottom: 0.5rem !important;
          }

          .pl-2,
          .px-2 {
            padding-left: 0.5rem !important;
          }

          .p-3 {
            padding: 1rem !important;
          }

          .pt-3,
          .py-3 {
            padding-top: 1rem !important;
          }

          .pr-3,
          .px-3 {
            padding-right: 1rem !important;
          }

          .pb-3,
          .py-3 {
            padding-bottom: 1rem !important;
          }

          .pl-3,
          .px-3 {
            padding-left: 1rem !important;
          }

          .p-4 {
            padding: 1.5rem !important;
          }

          .pt-4,
          .py-4 {
            padding-top: 1.5rem !important;
          }

          .pr-4,
          .px-4 {
            padding-right: 1.5rem !important;
          }

          .pb-4,
          .py-4 {
            padding-bottom: 1.5rem !important;
          }

          .pl-4,
          .px-4 {
            padding-left: 1.5rem !important;
          }

          .p-5 {
            padding: 3rem !important;
          }

          .pt-5,
          .py-5 {
            padding-top: 3rem !important;
          }

          .pr-5,
          .px-5 {
            padding-right: 3rem !important;
          }

          .pb-5,
          .py-5 {
            padding-bottom: 3rem !important;
          }

          .pl-5,
          .px-5 {
            padding-left: 3rem !important;
          }

          .m-auto {
            margin: auto !important;
          }

          .mt-auto,
          .my-auto {
            margin-top: auto !important;
          }

          .mr-auto,
          .mx-auto {
            margin-right: auto !important;
          }

          .mb-auto,
          .my-auto {
            margin-bottom: auto !important;
          }

          .ml-auto,
          .mx-auto {
            margin-left: auto !important;
          }

          .d-flex{
              display: flex;
          }

          .align-items-center {
              align-items: center;
          }

          .font-weight-bold{
              font-weight: bold;
          }

          .position-relative {position: relative}
          .position-absolute {position: absolute}

          .container{
              width: auto;
              max-width: 940px !important;
              padding: 0;
              background-color: white!important;
              margin: 0 auto;
          }
          .custom-red{
              color: #f51355 !important;
          }

          .bg-custom-transparent {
              background: rgba(255, 255, 255, 0.76);
          }

          .border-line-end{
              border-right: 1px solid #818080
          }

          ul{
              list-style: none;
              display: -webkit-box;
              display: -webkit-flex;
              display: flex;
              flex-direction: row;
              -webkit-flex-direction: row;
          }

          .event-detail li{
              -webkit-box-flex: 1;
              -webkit-flex: 1;
              flex: 1;
              padding-right: 80px;
              padding-bottom: 10px;
              margin-right: 80px;
          }

          .proposal-images li{
              -webkit-box-flex: 1;
              -webkit-flex: 1;
              flex: 1;
              width: 200px;
              height: 160px;
              margin-right: 20px;
          }

          .proposal-images li img{
              width: 100%;
              height: 100%;
          }
      </style>
  </head>
  <body>
    <div class="container bg-white p-0">
        <section class="position-relative">
            <img src="https://maryoku.s3.amazonaws.com/proposal/inspirationalPhotos/6071631fcfefec2676a08362/photo-0.png" style="width:100%;height: 500px"/>
            <div class="p-4 position-absolute bg-custom-transparent" style="top:0;left:0;right:0;height: 100px">
                <h3 class="font-weight-bold">Event Information  Details</h3>
                <ul class="event-detail mt-3">
                    <li class="border-line-end">
                        <label class="font-weight-bold">Name</label>
                        <div>Event</div>
                    </li>
                    <li class="border-line-end">
                        <label class="font-weight-bold">Date</label>
                        <div>Date</div>
                    </li>
                    <li class="">
                        <label class="font-weight-bold">Guest Arrival Time</label>
                        <div>Time</div>
                    </li>
                </ul>
            </div>
        </section>
        <section class="px-4 py-2">
            <h1 class="font-weight-bold">Dear Man,</h1>
            <p>It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.
            The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here,
            content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text,
            and a search for 'lorem ipsum' will uncover many web sites still in their infancy.
            Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
            </p>
            <div class="my-4">
                <h3 class="font-weight-bold d-flex align-items-center">
                <img class="mr-2" src="https://static-maryoku.s3.amazonaws.com/storage/icons/Vendor+Landing+Page/Asset+491.svg" width="30"/>
                    Our vision for your event</h3>
                <p>nd web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites
                still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose
                (injected humour and the like).</p>
            </div>
            <div>
                <div class="font-weight-bold">Some references to the experience you will get from us</div>
                <ul class="proposal-images">
                    <li>
                        <img src="https://maryoku.s3.amazonaws.com/proposal/inspirationalPhotos/60757eb2cfefec2676a084fe/photo-0.jpeg"/>
                    </li>
                    <li>
                        <img src="https://maryoku.s3.amazonaws.com/proposal/inspirationalPhotos/60757eb2cfefec2676a084fe/photo-1.png"/>
                    </li>
                    <li>
                        <img src="https://maryoku.s3.amazonaws.com/proposal/inspirationalPhotos/60757eb2cfefec2676a084fe/photo-2.png"/>
                    </li>
                </ul>
            </div>
            <div class="mt-4">
                <h3 class="font-weight-bold custom-red">About Us</h3>
                <p class="mt-2">
                    It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
                </p>
            </div>
            
        </section>
        <section class="px-4 py-2 mt-4">
            <div class="d-flex align-items-center py-2">
                <img class="mr-2" src="https://static-maryoku.s3.amazonaws.com/storage/icons/Submit%20Proposal/Asset 287.svg" width="16"/>
                <h3 class="font-weight-bold m-0">Our Policy</h3>
            </div>
            <p>What would you like to take from our suggested services?</p>
        </section>
        <section class="px-4 py-2">
            <div class="d-flex align-items-center py-2">
                <img class="mr-2" src="https://static-maryoku.s3.amazonaws.com/storage/icons/budget+screen/SVG/Asset%2010.svg" width="16"/>
                <h3 class="font-weight-bold m-0">Pricing  Details</h3>
            </div>
            <p></p>
        </section>
    </div>
  </body>
</html>

当我使用 wkhtmltopdf.exe 将此 html 转换为 pdf 时,结果 pdf 看起来不错。

wkhtmltopdf.exe proposal.html proposal.pdf

converted pdf

但是当我使用 grails pdf 渲染时,它看起来很糟糕。

pdfRenderingService.render(template: '/pdfs/proposal', model: [proposal: proposal]);

grails-app/views/pdfs/_proposal.gsp 中有一个 _proposal.gsp 文件。 _proposal.gsp 文件的内容与 html 文件相同。 pdfRenderingService 的渲染结果不正确。

Incorrect pdf file

wkhtmltopdf.exe 可以正确呈现 html 文件。 但是 grails 插件无法正确呈现。 grails 渲染有什么问题? 谢谢。

0 个答案:

没有答案
相关问题