使用JAVA和Itext7将HTML转换为PDF时获取NullPointerException

时间:2019-06-19 12:27:29

标签: java itext7 html2pdf

按照堆栈跟踪中的说明获取NPE。该代码适用于某些html文件。因此,我可以确认该问题是间歇性的。

如果仔细观察,html会有一个根标记,其中包括标头图像和页码,其余部分位于中。其背后的原因是,我希望在生成的pdf的每个页面上都包含图像和页面编号。

下面是我正在使用的示例代码:

``````
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ConverterProperties converterProperties = new ConverterProperties();
converterProperties.setCharset(StandardCharsets.UTF_8.name());
converterProperties.setImmediateFlush(false);
converterProperties.setCreateAcroForm(false);
FontProvider fontProvider = new DefaultFontProvider();
FontProgram fontProgram = 
FontProgramFactory.createFont("/fonts/arialuni.ttf");
fontProvider.addFont(fontProgram);
converterProperties.setFontProvider(fontProvider);
HtmlConverter.convertToPdf(html, outputStream, converterProperties);
outputStream.close(); 
``````

错误跟踪strace:

ERROR com.itextpdf.layout.renderer.TableRenderer  - Occupied area has not been initialized. Some of the cell's content might not end up placed correctly. 
java.lang.NullPointerException
    at com.itextpdf.layout.renderer.BlockRenderer.applyVerticalAlignment(BlockRenderer.java:630)
    at com.itextpdf.layout.renderer.TableRenderer.correctRowCellsOccupiedAreas(TableRenderer.java:1718)
    at com.itextpdf.layout.renderer.TableRenderer.correctLayoutedCellsOccupiedAreas(TableRenderer.java:1670)
    at com.itextpdf.layout.renderer.TableRenderer.layout(TableRenderer.java:736)
    at com.itextpdf.layout.renderer.TableRenderer.layout(TableRenderer.java:439)
    at com.itextpdf.layout.renderer.BlockRenderer.layout(BlockRenderer.java:219)
    at com.itextpdf.layout.renderer.BlockRenderer.layout(BlockRenderer.java:219)
    at com.itextpdf.layout.renderer.BlockRenderer.layout(BlockRenderer.java:219)
    at com.itextpdf.layout.renderer.BlockRenderer.layout(BlockRenderer.java:219)
    at com.itextpdf.layout.renderer.BlockRenderer.layout(BlockRenderer.java:219)
    at com.itextpdf.layout.renderer.BlockRenderer.layout(BlockRenderer.java:219)
    at com.itextpdf.layout.renderer.TableRenderer.layout(TableRenderer.java:570)
    at com.itextpdf.layout.renderer.BlockRenderer.layout(BlockRenderer.java:219)
    at com.itextpdf.layout.renderer.RootRenderer.addChild(RootRenderer.java:134)
    at com.itextpdf.html2pdf.attach.impl.layout.HtmlDocumentRenderer.addChild(HtmlDocumentRenderer.java:173)
    at com.itextpdf.layout.RootElement.createAndAddRendererSubTree(RootElement.java:377)
    at com.itextpdf.layout.RootElement.add(RootElement.java:106)
    at com.itextpdf.layout.Document.add(Document.java:160)
    at com.itextpdf.html2pdf.attach.impl.tags.HtmlTagWorker.processBlockChild(HtmlTagWorker.java:183)
    at com.itextpdf.html2pdf.attach.impl.tags.HtmlTagWorker.processTagChild(HtmlTagWorker.java:149)
    at com.itextpdf.html2pdf.attach.impl.tags.BodyTagWorker.processTagChild(BodyTagWorker.java:111)
    at com.itextpdf.html2pdf.attach.impl.DefaultHtmlProcessor.visit(DefaultHtmlProcessor.java:353)

已使用HTML:

    <!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8" />
      <title>My Report</title>
      <style> #remaining_sections tr,  td {text-align:left;border-bottom:#ffffff 1.00pt SOLID;height:15pt;} #header span div{position: relative;text-align:left;width:100pt;}   @page {size: portrait ;padding:5pt; margin:0.3in;border-top:1pt solid black;border-left:1pt solid black;border-bottom:1pt solid black;border-right:1pt solid black;} table { page-break-after:auto }  th    { page-break-inside:avoid; page-break-after:auto }  tr    { page-break-inside:avoid; page-break-after:auto }      td    { page-break-inside:avoid; page-break-after:auto }    thead { display:table-header-group}     tfoot { display:table-footer-group }#element { position: expression(fixed); top: 0in; left:0.1in;right:0.1in;bottom:0.1in; z-index: 10;}        a[href]:after { content: none !important; }   #element { position: fixed; top: 0in; left:0.1in;right:0.1in;bottom:0.1in; z-index: 10}     body{   background-color:#FFFFFF;font-family:"Arial Unicode MS";white-space:nowrap;font-size:9pt;}  .headers {  font-size:12pt; font-weight:bold; color:#555555;text-align:center;}   .bold {font-weight:bold;}     #remaining_sections {top:255pt;width:540pt;}        #main {top:13pt;left:22pt;width:568pt;}         #remaining_sections table { border: none;white-space: nowrap;font-family: "Arial Unicode MS";font-size: 9pt;border-collapse: collapse;width: 100%;height: auto;}    .theading { background-color:#FFFFFF;font-family: "Arial Unicode MS";font-size: 8pt;font-weight: bold;color: #555555;}      #remaining_sections th {padding:15px;}      #remaining_sections td {padding-left:15px;padding-right:15px;}#remaining_sections tbody tr:nth-child(odd) {background-color:#FFFFFF;}       #remaining_sections .total_td { white-space: nowrap;font-family: "Arial Unicode MS";font-size: 9pt;color: #2B446E;background-color:#FFFFFF;border:none;}        #remaining_sections .summary_td {white-space: nowrap;font-family: "Arial Unicode MS";font-size: 9pt;font-weight: bold;color: #2B446E;border:#828282 1.00pt SOLID; text-align:right;}    .no_background {background-color:#FFFFFF;}  .header_line_1 {border-top:#000000 2.00pt OUTSET;}  .aligning {border-collapse: inherit;text-align:left;padding-left:60px;} #summary_details_tr tr td {border-bottom:none;background-color:#FFFFFF;}#remaining_sections td { border-bottom:#828282 1.00pt SOLID;}#head_image {left:22pt;top:12pt;width:135pt;height:60pt;margin-right: auto; display: block;}#pageNoHead { left:22pt;top:2pt;width:110pt;height:8pt;margin-left: auto; display: block;}#pageNoHead:after { counter-increment: page; content: "Page " counter(page) " of " counter(pages) ; }</style>
   </head>
   <body style="OVERFLOW: auto">
      <div id="main">
      <table style="repeat-header: yes;repeat-footer: yes;">
         <thead>
            <tr>
               <th>
                  <div>
                  <div id='pageNoHead'/><img id=head_image  src='data:image/jpeg;base64,/image/2Q=='/></div>
               </th>
            </tr>
         </thead>
         <tbody>
            <tr>
               <td>

                  <div id="header">
                     <div style='top:72pt;left:22pt; text-align:right;margin-right:30pt'><span style='text-align:right;margin-right:74pt;'>MY INVOICE</span></div>
                     <span>
                        <div style="top:20pt;left:263pt;text-align:right;">DATE:</div>
                        <div style="top:7pt;left:388pt;text-align:right;">31MAY18</div>
                        <div style="top:6pt;left:290pt;text-align:right;">NUM:</div>
                        <div style="top:-6pt;left:431pt;text-align:right;">1234567890</div>
                        <div style="top:-6pt;left:290pt;text-align:right;">HEAD:</div>
                        <div style="top:-17pt;left:369pt;text-align:right;">39</div>
                        <div style="top:-6pt;left:285pt;text-align:right; color:white;">SEQUENCE:</div>
                        <div style="top:-17pt;left:369pt;text-align:right; color:white;">39</div>
                     </span>
                     <span>
                        <div style="top:15pt;left:20pt;">MY COMPANY LIMITED</div>
                        <div style="top:17pt;left:20pt;">MY FARM</div>
                        <div style="top:15pt;left:20pt;">MY TOWN</div>
                        <div style="top:13pt;left:20pt;">MY CITY</div>
                        <div style="top:11pt;left:20pt;">MY PIN</div>
                        <div style="top:9pt;left:20pt;"></div>
                     </span>
                     <div style="left:5pt;width:520pt;text-align:right;padding-bottom: 35pt;">RANDOM HEADER</div>
                  </div>
                  <div id="remaining_sections">
                     <div id="introduction">                        
                           FOR ADVICE ONLY - ALL CHANGES HAVE BEEN APPLIED AT ZERO LEVEL</br></br>THIS DETAILS CHANGES FOR YOUR MOTOR INDUSTRY AND RECEIVED BY BUS FOR </br>THE PERIOD OF 01 MAY 2018 TO 31 MAY 2018.</br></br>                           
                           </br>
                           <div id="summary_of_charges">
                              <table cellspacing='0' cellpadding='0'>
                                 <tbody id='summary_details_tr'>
                                    <tr>
                                       <td colspan='8'>HEAD  </td>
                                    </tr>                                    

                                    <tr>
                                       <td>1234567890  </td>
                                       <td>HEAD TO CAR  </td>
                                       <td>INR  </td>
                                       <td>1234567890  </td>
                                       <td>1234567890  </td>
                                       <td style='text-align:right;'>4,160.10  </td>
                                       <td>1234567890  </td>
                                       <td>DR  </td>
                                    </tr>
                                 </tbody>
                              </table>
                           </div>
                           </br>
                           <div id="summary_of_vat">
                              <table cellspacing='0' cellpadding='0'>
                                 <tbody id='summary_details_tr'>
                                    <tr>
                                       <td colspan='8'>HEAD OF GST  </td>
                                    </tr>

                                    <tr height='30'>
                                       <td>1234567890  </td>
                                       <td>GST NO:  </td>
                                       <td>1234567890  </td>
                                       <td>1234567890  </td>
                                       <td>1234567890  </td>
                                       <td>1234567890  </td>
                                       <td>1234567890  </td>
                                       <td>1234567890  </td>
                                       <td>1234567890  </td>
                                    <tr>    
                                 </tbody>
                              </table>
                              </br> 
                              <div>GST IS APPLIED AT 18.0000% TO SOME CHARGES SHOWN ABOVE. ALL OTHER CHARGES ARE GST EXEMPT AND NO</div>
                              <div>INPUT TAX MAY BE RECLAIMED.</div>
                           </div>
                           </br></br>
                           <div id="transaction">
                              <table id='trans_dtaa' cellspacing='0' cellpadding='0'>
                                 <thead>
                                    <tr>
                                       <th colspan='8' class='no_background' style='padding:0pt;border:none;'>
                                          <div class='header_line_1 headers'>HEADER</div>
                                          <div class='header_line_1'></div>
                                          </br>         
                                       </th>
                                    </tr>
                                    <tr class='theading'>
                                       <th>HEAD</th>
                                       <th>HEAD NO</th>
                                       <th style='text-align:right;'>HEAD</th>
                                       <th style='text-align:right;'>HEAD</th>
                                       <th style='text-align:right;'>HEAD</th>
                                       <th style='text-align:right;'>NON-HEAD</th>
                                       <th style='text-align:right;'>HEAD</th>
                                       <th style='text-align:right;'>HEAD</th>
                                    </tr>
                                 </thead>
                                 <tbody id='transaction_details_tr'>

                                    <tr>
                                       <td>18-MAY-18  </td>
                                       <td>1234567890  </td>
                                       <td style='text-align:right;'>80  </td>
                                       <td style='text-align:right;'>4,206.61  </td>
                                       <td style='text-align:right;'>39.48  </td>
                                       <td style='text-align:right;'>0.00  </td>
                                       <td style='text-align:right;'>0.00  </td>
                                       <td style='text-align:right;'>4,167.13  </td>
                                    </tr>

                                 </tbody>
                              </table>
                           </div>
                           </br></br>
                           <div id="transaction_item_summary">
                              <table id='deposit_summary_table' cellspacing='0' cellpadding='0'>
                                 <thead>
                                    <tr>
                                       <th colspan='7' class='no_background' style='padding:0pt;border:none;'>
                                          <div class='header_line_1 headers'>NEW HEADER</div>
                                          <div class='header_line_1'></div>
                                          </br>                 
                                          <div style='border-top:#FFFFFF 1.00pt OUTSET;'></div>
                                       </th>
                                    </tr>
                                 </thead>
                                 <tbody id='deposit_summary_tr'>
                                    <tr>
                                       <td class='summary_td'>SALES:  </td>
                                       <td class='summary_td'>7,805  </td>
                                       <td class='summary_td'>338,939.07  </td>
                                       <td class='summary_td'>DB:  </td>
                                       <td class='summary_td'>0  </td>
                                       <td class='summary_td'>0.00  </td>
                                    </tr>
                                    <tr>
                                       <td class='summary_td'>RETURN:  </td>
                                       <td class='summary_td'>61  </td>
                                       <td class='summary_td'>2,355.86  </td>
                                       <td class='summary_td'>CR :  </td>
                                       <td class='summary_td'>0  </td>
                                       <td class='summary_td'>0.00  </td>
                                    </tr>
                                    <tr>
                                       <td class='total_td summary_td'>TOTAL:  </td>
                                       <td class='total_td summary_td'>7,866  </td>
                                       <td class='total_td summary_td'>336,583.21  </td>
                                       <td class='total_td summary_td'>TOTAL:  </td>
                                       <td class='total_td summary_td'>0  </td>
                                       <td class='total_td summary_td'>0.00  </td>
                                    </tr>
                                 </tbody>
                              </table>
                           </div>
                           </br></br>
                           <div id="card_summary">
                              <table cellspacing='0' cellpadding='0'>
                                 <thead>
                                    <tr>
                                       <th colspan='8' class='no_background' style='padding:0pt;border:none;'>
                                          <div class='header_line_1 headers'>HEADER</div>
                                          <div class='header_line_1'></div>
                                          </br>         
                                       </th>
                                    </tr>
                                    <tr class='theading'>
                                       <th>HEAD</th>
                                       <th style='text-align:center;'>HEAD</th>
                                       <th style='text-align:right;'>HEAD</th>
                                       <th style='text-align:right;'> HEAD</th>
                                       <th style='text-align:right;'>HEAD</th>
                                       <th style='text-align:right;'>HEAD</th>
                                       <th style='text-align:right;'>HEAD</th>
                                    </tr>
                                 </thead>
                                 <tbody id='card_summary_details_tr'>

                                    <tr>
                                       <td>1234567890  </td>
                                       <td style='text-align:center;'>358.31  </td>
                                       <td style='text-align:right;'>2,298.60  </td>
                                       <td style='text-align:right;'>0.00  </td>
                                       <td style='text-align:right;'>0.00  </td>
                                       <td style='text-align:right;'>0.00  </td>
                                       <td style='text-align:right;'>0.00  </td>
                                    </tr>
                                 </tbody>
                              </table>
                           </div>
                           </br></br>
                           <div id="transaction_charges">
                              <table cellspacing='0' cellpadding='0'>
                                 <thead>
                                    <tr>
                                       <th colspan='8' class='no_background' style='padding:0pt;border:none;'>
                                          <div class='header_line_1 headers'>HEADER</div>
                                          <div class='header_line_1'></div>
                                          </br>         
                                       </th>
                                    </tr>
                                 </thead>
                              </table>
                              <table cellspacing='0' cellpadding='0'>
                                 <thead>
                                    <tr>
                                       <td colspan='8' class='no_background headers' style='text-align:left;padding:0pt;border:none;'>INR  </td>
                                    </tr>
                                    <tr class='theading'>
                                       <th>HEAD</th>
                                       <th> HEAD</th>
                                       <th style='text-align:right;'>HEAD</th>
                                       <th style='text-align:right;'>HEAD</th>
                                       <th>HEAD<br> HEAD</th>
                                       <th>HEAD <br>HEAD</th>
                                       <th style='text-align:right;'>HEAD</th>
                                       <th style='text-align:right;'>HEAD</th>
                                    </tr>
                                 </thead>
                                 <tbody id='deposit_details_tr'>

                                    <tr>
                                       <td>TEXT  </td>
                                       <td style='text-align:right;'>2  </td>
                                       <td style='text-align:right;'>330.40  </td>
                                       <td style='text-align:right;'>165.20  </td>
                                       <td>1.3240  </td>
                                       <td>0.0000  </td>
                                       <td style='text-align:right;'>4.37  </td>
                                       <td style='text-align:right;'>INR  </td>
                                    </tr>

                                 </tbody>
                              </table>
                              </br>
                           </div>
                           </br></br>
                           <div id="interchange_and_other_charges">
                              <table cellspacing='0' cellpadding='0'>
                                 <thead>
                                    <tr>
                                       <th colspan='8' class='no_background' style='padding:0pt;border:none;'>
                                          <div class='header_line_1 headers'>HEADER</div>
                                          <div class='header_line_1'></div>
                                          </br>             
                                       </th>
                                    </tr>
                                 </thead>
                              </table>
                              <table cellspacing='0' cellpadding='0'>
                                 <thead>
                                    <tr>
                                       <td colspan='8' class='no_background headers' style='text-align:left;padding:0pt;border:none;'>INR  </td>
                                    </tr>
                                    <tr class='theading'>
                                       <th>HEAD</th>
                                       <th style='text-align:right;'>HEAD</th>
                                       <th style='text-align:right;'>HEAD</th>
                                       <th style='text-align:right;'>HEAD </th>
                                       <th style='text-align:right;'>HEAD</th>
                                    </tr>
                                 </thead>
                                 <tbody id='interchange_and_other_charges_details_tr'>
                                    <tr>
                                       <td>MY HEAD  </td>
                                       <td style='text-align:right;'>50  </td>
                                       <td style='text-align:right;'>3,246.63  </td>
                                       <td style='text-align:right;'>1.95  </td>
                                       <td style='text-align:right;'>INR  </td>
                                    </tr>

                                 </tbody>
                              </table>
                              </br>
                           </div>
                           </br></br>
                           <div id="chargebacks_rejects"></div>
                           </br></br>
                           <div id="other_fees_section">
                              <table cellspacing='0' cellpadding='0'>
                                 <thead>
                                    <tr>
                                       <th colspan='8' class='no_background' style='padding:0pt;border:none;'>
                                          <div class='header_line_1 headers'>HEADER</div>
                                          <div class='header_line_1'></div>
                                          </br>     
                                       </th>
                                    </tr>
                                 </thead>
                                 <tbody></tbody>
                              </table>
                              <table cellspacing='0' cellpadding='0'>
                                 <thead>
                                    <tr>
                                       <th colspan='8' class='no_background' style='padding:0pt;border:none;'>
                                          <div style='text-align:left;' class='headers'>GST APPLICABLE FEES</div>
                                       </th>
                                    </tr>
                                    <tr class='theading'>
                                       <th>CARD</th>
                                       <th>CARD</th>
                                       <th>CARD</th>
                                       <th style='text-align:right;'>CARD</th>
                                       <th style='text-align:left;' >CARD</th>
                                       <th style='text-align:right;'>CARD</th>
                                       <th style='text-align:right;'>CARD</th>
                                    </tr>
                                 </thead>
                                 <tbody id='vat_applicable_fees_details_tr'>
                                    <tr>
                                       <td>   </td>
                                       <td>1234567890  </td>
                                       <td>GST  </td>
                                       <td style='text-align:right;'>2  </td>
                                       <td>3.5000  </td>
                                       <td style='text-align:right;'>7.00  </td>
                                       <td style='text-align:center;'>INR  </td>
                                    </tr>

                                 </tbody>
                              </table>
                              </br>
                           </div>
                           <div id="other_fees_section2">
                              <table cellspacing='0' cellpadding='0'>
                                 <thead>
                                    <div style='text-align:left;' class='headers'>HEADER</div>
                                    </th></tr>          
                                    <tr class='theading'>
                                       <th>CARD</th>
                                       <th>CARD</th>
                                       <th>CARD</th>
                                       <th style='text-align:right;'>CARD</th>
                                       <th style='text-align:left;' >CARD</th>
                                       <th style='text-align:right;'>CARD</th>
                                       <th style='text-align:right;'>CARD</th>
                                    </tr>
                                 </thead>
                                 <tbody id='non_vat_applicable_fees_details_tr'>

                                    <tr>
                                       <td>   </td>
                                       <td>1234567890  </td>
                                       <td>CARD  </td>
                                       <td style='text-align:right;'>0  </td>
                                       <td>000.0000  </td>
                                       <td style='text-align:right;'>-0.32  </td>
                                       <td style='text-align:center;'>INR  </td>
                                    </tr>
                                    <tr class='total_td'>
                                       <td colspan='4'>  </td>
                                       <td>SUB TOTAL  </td>
                                       <td style='text-align:right;'>305.53  </td>
                                       <td style='text-align:center;'>INR  </td>
                                    </tr>
                                    <tr class='total_td'>
                                       <td colspan='4'>  </td>
                                       <td>TOTAL  </td>
                                       <td style='text-align:right;'>586.33  </td>
                                       <td style='text-align:center;'>INR  </td>
                                    </tr>
                                 </tbody>
                              </table>
                           </div>
                           </br></br>

                        </div>
                     </div>
                 </td>
            </tr>
         </tbody>
      </table>
      </div>
      <div id="vertical_border" style="left:600pt;" height="(doc_height+15)px;" class="thick_border"></div>
      <div id="horizontal_border" style="left:0pt; width:600pt;" height="(doc_height+25)px;" class="thick_border"></div>
   </body>
</HTML>

1 个答案:

答案 0 :(得分:0)

当我将HTML放入HTML检查器(例如https://validator.w3.org/nu/#textarea)时,我会看到许多错误。特别是,它不喜欢自动关闭的62638: "/azure-pipelines.yml: Could not get the latest source version for repository MySolution hosted on Azure Repos using ref refs/heads/$(Build.SourceBranch)."

<div />

如果您用结尾的 <div> <div id='pageNoHead'/><img id=head_image src='data:image/jpeg;base64,/image/2Q=='/></div> 显式关闭<div id='pageNoHead'/>,会发生什么?例如:

</div>

此外,我将检查并修复您的HTML其余部分。其中一些是:

  • <div> <div id='pageNoHead'></div> <img id=head_image src='data:image/jpeg;base64,/image/2Q=='/> </div> is not correct,应为</br><br>
  • 有2个具有相同ID(<br/>)的表主体。
  • 有些表行未关闭,例如<tbody id='summary_details_tr'>(看起来您应该关闭上一行,即<tr> </tbody>

可能还有其他错误,我在您拥有的某些表结构上链接到barfs的HTML检查器。我认为问题出在HTML格式错误,而不是您的代码。