Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Table row on new page - render issue #191

Closed
accordionpeas opened this issue Jan 21, 2020 · 6 comments
Closed

Table row on new page - render issue #191

accordionpeas opened this issue Jan 21, 2020 · 6 comments

Comments

@accordionpeas
Copy link

Hi,

I'm seeing various different render issues on table rows that break onto a new page. Sometimes the row overlaps with the row below it, sometimes the the spacing within a cell is increased, etc. I'm struggling to pin point exactly what is causing this so its been difficult to provide a small code sample that reproduces it but I've managed to find something that shows one of the render issues shown in the attached pdf:

table-row-render-issue.pdf

const doc = new pdf.Document({
  font: helveticaFont,
});

const headerTable = doc
  .header()
  .table({
    widths: [null, null],
  })
  .row();

headerTable.cell('Heading left', {
  textAlign: 'left',
  paddingBottom: 10,
  color: 0x808080,
});
  
headerTable.cell('Heading right', {
  textAlign: 'right',
  paddingBottom: 10,
  color: 0x808080,
});

const footer = doc.footer();
const footerTable = footer
  .table({
    widths: [null, null],
  })
  .row();

footerTable.cell('Footer left', {
  color: 0x808080,
});

footerTable.cell('Footer right', {
  color: 0x808080,
});

footer.pageNumber({
  textAlign: 'right',
  color: 0x808080,
});

doc
  .cell({
    paddingBottom: 20,
  })
  .text('Heading', {
    fontSize: 20,
  });

const table = doc.table({
  widths: [100, null],
  borderWidth: 1,
  borderColor: 0xf00f00,
});

[...Array(5)].map((item, index) => {
  const row = table.row();

  row.cell(`heading ${index}`, {
    padding: 12,
  });

  const cell = row.cell();
    
  cell.cell(`value ${index} - 1`, {
    padding: 12,
  });

  cell.cell(`value ${index} - 2`, {
    padding: 10,
  });

  cell.cell(`value ${index} - 3`, {
    padding: 10,
  });

  cell.cell(`value ${index} - 4`, {
    padding: 10,
  });

});

Any help would be greatly appreciated.

Thanks,

rkusa added a commit that referenced this issue Jan 30, 2020
@rkusa
Copy link
Owner

rkusa commented Jan 30, 2020

Thanks for the report and for providing a minimal example, highly appreciated!

Version 2.3.4 should fix the issue in your example above as well as some other issues I saw while debugging the one of your example.

Please let me know if it works for you now and if yous till see other issues.

@accordionpeas
Copy link
Author

accordionpeas commented Jan 31, 2020

Hi,

Thanks so much for getting back to me and releasing a new version. The changes you've made have indeed fixed the issue produced by the code snippet I provided. However, I'm still seeing an issue with overlapping text in a row that has broken onto a new page. I've tried to cut my application code down to the minimum I can and still produce the issue. Please see the pdf attached and the code below.

table-row-text-overlap.pdf

Thanks,

const renderTable = ({ rows, doc, headingWidth = 125 }) => {
  const borderColor = 0xe2e3e5;

  const table = doc.cell({
    paddingBottom: 30,
  }).table({
    widths: [null],
    borderHorizontalWidth: 1,
    borderColor,
  });

  for (let i = 0; i < rows.length; i += 1) {
    const values = rows[i];
    const cell = table.row().cell();

    const innerTable = cell.table({
      widths: [headingWidth, null],
      borderVerticalWidth: 1,
      borderColor,
    });

    for (let j = 0; j < values.length; j += 1) {
      const { heading, value } = values[j];

      const row = innerTable.row({
        paddingTop: 5,
        paddingRight: 5,
        paddingLeft: 5,
        paddingBottom: j === values.length - 1 ? 5 : 0,
      });

      row.cell(heading, {
        font: helveticaBoldFont,
        textAlign: 'right',
      });

      row.cell(value);
    }
  }
};

const doc = new pdf.Document({
  font: helveticaFont,
});

doc.cell('Received Lines', {
 font: helveticaBoldFont,
 fontSize: 20,
 paddingBottom: 10,
});

const rows = [
  [{
    "heading": "Hop 1",
    "value": "Wed, 20 Nov 2019 13:22:48 +0100"
  }, {
    "heading": "Received",
    "value": "Wed, 20 Nov 2019 13:22:48 +0100"
  }],
  [{
    "heading": "Hop 2",
    "value": "Wed, 20 Nov 2019 12:22:43.941 +0000 (UTC)"
  }, {
    "heading": "Received from",
    "value": "[12.12.0.12] (unknown [123.123.123.12])\t"
  }, {
    "heading": "Received by",
    "value": " 1234567890123456.12345678.123 (12) with ESMTP id 1234567890123456789012 for <12345.12345@12345678.com>"
  }],
  [{
    "heading": "Hop 3",
    "value": ""
  }, {
    "heading": "Received",
    "value": "by 1234567890123456.12345678.123 with SMTP id 1234567890123456-12345-12345678-4        2019-11-20 12:22:44.363486548 +0000 UTC m=+11203.761880229"
  }],
  [{
    "heading": "Hop 4",
    "value": "20 Nov 2019 12:22:45 -0000"
  }, {
    "heading": "Received from",
    "value": "123456789.12345678-1234.12345678.123 (HELO 123456789.12345678-1234.12345678.123) (12.12.12.12)  "
  }, {
    "heading": "Received by",
    "value": " 123456-12.12345-123.12345678901.com with 12345-123-12345-123-12345 encrypted SMTP"
  }],
  [{
    "heading": "Hop 1",
    "value": "Wed, 20 Nov 2019 13:22:48 +0100"
  }, {
    "heading": "Received",
    "value": "Wed, 20 Nov 2019 13:22:48 +0100"
  }],
  [{
    "heading": "Hop 2",
    "value": "Wed, 20 Nov 2019 12:22:43.941 +0000 (UTC)"
  }, {
    "heading": "Received from",
    "value": "[12.12.0.12] (unknown [123.123.123.12])\t"
  }, {
    "heading": "Received by",
    "value": " 1234567890123456.12345678.123 (12) with ESMTP id 1234567890123456789012 for <12345.12345@12345678.com>"
  }],
  [{
    "heading": "Hop 3",
    "value": ""
  }, {
    "heading": "Received",
    "value": "by 1234567890123456.12345678.123 with SMTP id 1234567890123456-12345-12345678-4        2019-11-20 12:22:44.363486548 +0000 UTC m=+11203.761880229"
  }],
  [{
    "heading": "Hop 4",
    "value": "20 Nov 2019 12:22:45 -0000"
  }, {
    "heading": "Received from",
    "value": "123456789.12345678-1234.12345678.123 (HELO 123456789.12345678-1234.12345678.123) (12.12.12.12)  "
  }, {
    "heading": "Received by",
    "value": " server-12.12345-123.12345678901.com with 12345-123-12345-123-12345 encrypted SMTP"
  }],
  [{
    "heading": "Hop 5",
    "value": "20 Nov 2019 12:22:45 -0000"
  }, {
    "heading": "Received",
    "value": "(12345 2001 invoked from 123work)"
  }],
  [{
    "heading": "Hop 6",
    "value": "Wed, 20 Nov 2019 12:22:46 +0000"
  }, {
    "heading": "Received from",
    "value": "[12.123.12.123] (using 12345.2 with cipher 123-123-12345-123-12345-12345-12345 (256 bits)) "
  }, {
    "heading": "Received by",
    "value": " server-2.12345.12-1.12-1234-1.123.123456.123 id 12/12-123456-12345678"
  }],
  [{
    "heading": "Hop 7",
    "value": "Wed, 20 Nov 2019 12:24:44 +0000 (GMT)"
  }, {
    "heading": "Received from",
    "value": "12345.1234567.12345678901.com (12345.1234567.12345678901.com [123.123.123.12]) "
  }, {
    "heading": "Received by",
    "value": " 12345678.12345678.com (123) with 12345 id 12345678901 for <12345.12345@12345678.com>"
  }],
  [{
    "heading": "Hop 8",
    "value": "Wed, 20 Nov 2019 12:22:48 +0000"
  }, {
    "heading": "Received from",
    "value": "12345678.12345678.com (12.123.123.12) "
  }, {
    "heading": "Received by",
    "value": " 12345.12345678.local (12.123.123.12) with 123456789 SMTP Server id 12.1.123.1"
  }]
];

renderTable({ doc, rows });

doc.end();

@accordionpeas
Copy link
Author

Hi @rkusa , sorry to chase - have you had any chance to look into the issue described above?

@rkusa
Copy link
Owner

rkusa commented Feb 21, 2020

Hi @rkusa , sorry to chase - have you had any chance to look into the issue described above?

Don't worry, in this case it was good that you are asking again, since I've somehow missed the notification for your comment.

I found the bug. When moving already rendered stuff to the next page, the cells rendered afterwards must be moved down by the height of the moved stuff. However, this only works for the first cell and is bugged for all succeeding cells.

Unfortunately, I was unable to find a reasonable solution - at least during the time I reserved for this issue today. It seems that tables in tables (or tables in cells) isn't working very reliable, yet. A workaround for now would be to not nest tables and achieve the horizontal border grouping via the borderHorizontalWidths option:

  const renderTable = ({ rows, doc, headingWidth = 125 }) => {
    const borderColor = 0xe2e3e5;

    const table = doc.table({
      widths: [headingWidth, null],
      borderVerticalWidth: 1,
      borderHorizontalWidths: (i) => {
        // TODO: something else that takes into account that some "groups" have only 2 rows
        return i % 3 === 0
      },
      borderColor,
    });

    for (let i = 0; i < rows.length; i += 1) {
      const values = rows[i];

      for (let j = 0; j < values.length; j += 1) {
        const { heading, value } = values[j];

        const row = table.row({
          paddingTop: 5,
          paddingRight: 5,
          paddingLeft: 5,
          paddingBottom: j === values.length - 1 ? 5 : 0,
        });

        row.cell(heading, {
          font: helveticaBoldFont,
          textAlign: 'right',
        });

        row.cell(value);
      }
    }
  };

@accordionpeas
Copy link
Author

@rkusa Your solution has solved the issue for me. Thanks so much.

@rkusa
Copy link
Owner

rkusa commented Mar 3, 2020

@rkusa Your solution has solved the issue for me. Thanks so much.

Cool - I am glad we found a workaround until the issue is fixed. I've moved the remaining bug into a separate issue #203. Feel free to reopen this issue (or open a new one) if you encounter anything else. Thanks again for the report!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants