Sanakhatun Shaikh
Sanakhatun Shaikh

Reputation: 2339

How to generate html table with dynamic values in html when using react-native-html-to-pdf library in react native?

I want to generate pdf in my react native app. In which I want to display table where rows and its data are generated dynamically onload of document. I have generated that table using html and javascript but now the problem is when pdf was generated, javascript code was not rendered. only static html code was displayed on the pdf as result.

I'm using react-native-html-to-pdf library in my project. I may find difficulty that how do I iterate n all. I just able to print static string of html but not of dynamic data inside it.

Require immediate help. Thank you!

Code:

import React, { Component } from 'react';
import { View, Text, TouchableOpacity,TouchableHighlight} from 'react-native';
import RNHTMLtoPDF from 'react-native-html-to-pdf';

export default class CreatePDFExample extends Component{

    async createPDF() {
    let options = {

      html: `<!DOCTYPE html>
<html>
<head>
    <title>Report</title>
    <style>
        .mainContainer {
            width: 100%;
            border: 2px solid #000;
            border-bottom-width: 0px;
        }

        .headerContainer {
            text-align: center;
            border-bottom: 2px solid #000;
        }

        .middleContainer {
            margin-left: 5%;
            margin-top: 5%;
            margin-bottom: 1%;
        }

        .tableContent{
            width: 100%;
            border-collapse: collapse;
            border-top: 0px solid #000;
        }
        .tableContent td{
            text-align: center;
        }

        .bottomline {
            width: 100%;
            border-color: #000;
            border-style: solid;
            bottom-width: 1px;
            border-top-width: 0px;
        }
        hr{
            border: 1px solid #000; 
            margin-left: 10%;
            margin-right: 10%;
        }
        .sign td{
            border: 2px solid #000;
            padding-top: 5%;
            padding-bottom: 5%;
        }


    </style>

    <script type="text/javascript">


          function addRow() {
            var table = document.getElementById("tble");

            var colCount = table.rows[0].cells.length;   
            var rowCount = 5;  //length of database items

            for(var i = 0; i < rowCount; i++){

                var row = table.insertRow(1);     //Insert Row from position 1

                var srNo = row.insertCell(0);
                var date = row.insertCell(1);
                var particular = row.insertCell(2);
                var type = row.insertCell(3);
                var currency = row.insertCell(4);
                var amount = row.insertCell(5);
                var remark = row.insertCell(6);

                for (var j = 0; j < colCount; j++){
                    srNo.innerHTML = "1";
                    date.innerHTML = "xxxx";
                    particular.innerHTML = "xxxx";
                    type.innerHTML = "xxxx";
                    currency.innerHTML = "xxxx";
                    amount.innerHTML = "xxx";
                    remark.innerHTML = "xxxx";
                }
            }     
        }

    </script>
</head>

<body onload="addRow()">
    <div class="mainContainer">

        <div class="headerContainer">
            <h3>MY SHEET</h3>
        </div>

        <div class="middleContainer">
            <table>
                <tr>
                    <td><b>Name:-</b></td>
                    <td></td>
                </tr>

                <tr>
                    <td><b>Destination:-</b></td>
                    <td></td>
                </tr>

                <tr>
                    <td><b>Date:-</b></td>
                    <td></td>
                </tr>
            </table>
        </div>

        <div>
            <table id = "tble" class="tableContent" border="1">
                <tr style = "border: 2px solid #000">
                    <th>Sr.No</th>
                    <th>Date</th>
                    <th>Particulars</th>
                    <th>Type</th> 
                    <th>Currency</th>
                    <th>Amount</th>
                    <th>Remarks</th>
                </tr>

                <tr style = "border: 2px solid #000">
                    <td></td>
                    <td colspan="2"><b>TOTAL</b></td>
                    <td style="text-align: right"><b></b></td>
                    <td style="text-align: right"><b></b></td>
                    <td style="text-align: right"><b></b></td>
                    <td style="text-align: right"><b></b></td>
                </tr>


            </table>
        </div>


    </div>
</body>

</html>`,

      fileName: 'test',
      directory: 'docs'
    };

    let file = await RNHTMLtoPDF.convert(options);
    console.log(file.filePath);
  }


  render() {
      return(
          <View>
        <TouchableHighlight onPress={this.createPDF.bind(this)}>
        <Text>Create PDF</Text>
      </TouchableHighlight>
    </View>
      );
  } 
} 

Upvotes: 1

Views: 2498

Answers (2)

Rahmad Al Habib
Rahmad Al Habib

Reputation: 330

Push row data into array, and render with back tick,

Here to push into array

this.reportData.push(
              `<tr style="text-align:center">
                <td>${val.prevId}</td>
                <td>2</td>
                <td>3</td>
                <td>4</td>
              </tr>`,
            );

and here to render

await RNPrint.print({
      html: `<html>

      <head>
          <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
          <style>
              body {
                  font-family: calibri;
              }
      
              table,
              tr,
              td {
                  border: 1px solid #30BCC9;
                  border-collapse: collapse;
              }
      
              .page_break {
                  page-break-before: always;
              }
      
              .badge {
                  display: inline-block;
                  padding: 0.25em 0.4em;
                  font-size: 72%;
                  font-weight: 300;
                  line-height: 1;
                  text-align: center;
                  white-space: nowrap;
                  vertical-align: baseline;
                  border-radius: 0.25rem;
                  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
              }
      
              .badge-pill {
                  padding-right: 0.6em;
                  padding-left: 0.6em;
                  border-radius: 10rem;
              }
      
              .badge-info {
                  color: #fff;
                  background-color: #30BCC9;
              }
      
              .white {
                  border-color: #fff !important;
              }
          </style>
      </head>
      
      <body>
          <div style="width: 100%; text-align: center;">
              <h1 style="background-color: #30BCC9; color: #fff; padding: 20px;">KBC FUTSAL</h1>
              <h5 style="color: #30BCC9;">Jl. Kerja Bakti No.22, Pondok Cina, Kota Depok, Jawa Barat 16424</h5>
              <hr style="border-top: 2px solid #30BCC9;">
          </div>
          <h2 style="font-weight: bold;">Laporan Penyewaan <sup class="badge badge-pill badge-info"
                  style="font-weight: 300 !important;"> ${moment(date).format(
                    'DD MMMM YYYY',
                  )} - ${moment(dateTo).format('DD MMMM YYYY')}</sup></h2>
          <table cellpadding="5" style="width: 100%">
              <thead>
                  <tr style="text-align: center; background-color: #30BCC9; color: #fff;">
                      <td class="white">ID</td>
                      <td class="white">Nama Team</td>
                      <td class="white">Tanggal</td>
                      <td class="white">Lama Main</td>
                  </tr>
              </thead>
              <tbody>
                  ${reportData}
              </tbody>
          </table>
          <div style="text-align: right; margin-top: 25px; margin-right: 50px;">Depok, ${moment().format(
            'DD MMMM YYYY',
          )}</div>
      </body>
      
      </html>`,
    });

Upvotes: 1

Elise Chant
Elise Chant

Reputation: 5196

Just use a simple ES6 template function to pass your dynamic data.

Such as

createTemplate = ({ firstName = 'Roger' }) => {
  return `
    <html>
    //...
      <p>${firstName}</p>
    </html>
  }`
}

And then,

async createPDF() {
  let options = {
    html: createTemplate({ name: 'Sanakhatun' }),
  };

  let file = await RNHTMLtoPDF.convert(options)
  // ...
}

Upvotes: 0

Related Questions