Divide the information in the table across several pages for easier printing

I have encountered an architectural challenge with my server-side React app. The app renders charts and tables with page breaks in between to allow a puppeteer instance to print the report for users in another application.

The issue I'm facing is making the data printable without manual pagination. The data needs to flow seamlessly, extending until a page break is necessary, then continuing onto a new page for the next set of information. The complexity lies in the dynamic nature of the data, including varying row heights and widths.

My current approach involves measuring the table's height after each row insertion to determine if it exceeds the max height limit. If it does, a new table with a page break is initiated.

I've explored existing solutions like applying CSS page break rules but found them unsuitable due to specific requirements like custom headers and footers displaying metadata related to the content.

I have provided a sample code snippet in this CodePen, demonstrating the layout I'm trying to achieve. The footer element should appear on both printed pages and reflect the number of rows displayed per page dynamically, which eliminates the possibility of using a static footer within the table structure.

I am considering hiding the table during rendering, gradually calculating its height as rows are added to implement my initial method effectively. However, I remain open to alternative suggestions or insights from others familiar with such challenges.

Answer №1

Okay, I believe I have figured it out. While there is room for improvement and optimization in the code, here is the basic idea: https://codepen.io/nicholaswilson/pen/abJpLYE. Currently, I am dividing the tables after they surpass a certain height, but I plan to refine this later on. The concept is clear.

Essentially, the approach involves constructing a 4D array to manage the instances of tables that require rendering. Then, in componentDidMount() and componentDidUpdate(), new tables are incorporated into the state when necessary:

componentDidMount() {
const { tableData } = this.props;

if (this.state.currentRowIndex === 0) {
  // initial setup
  this.setState((state, props) => {
    const tables = state.tables;
    tables.push([tableData.data[state.currentRowIndex]]); // add first new table and its first row
    return {
      tables,
      currentRowIndex: state.currentRowIndex + 1,
      currentTableIndex: 0
    };
  });
}

}

componentDidUpdate() {
    const { tableData } = this.props;
    if (this.state.currentRowIndex < tableData.data.length) {
      this.setState((state, props) => {
        const tables = state.tables;
        const currentTableHeight = this.tableRefs[this.state.currentTableIndex]
          .clientHeight;
        console.log(
          `Table ${this.state.currentTableIndex} height: ${currentTableHeight}`
        );
        if (currentTableHeight > MAX_TABLE_HEIGHT_IN_PIXELS) {
          // add a new table based on this condition
          tables.push([tableData.data[state.currentRowIndex]]);
          return {
            tables,
            currentRowIndex: state.currentRowIndex + 1,
            currentTableIndex: state.currentTableIndex + 1
          };
        } else {
          tables[state.currentTableIndex].push(
            tableData.data[state.currentRowIndex]
          ); // add new row to existing table
          return {
            tables,
            currentRowIndex: state.currentRowIndex + 1,
            currentTableIndex: state.currentTableIndex
          };
        }
      });
    }
  }

Refer to the codepen for the complete implementation details.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for making Ajax crawlable with jQuery

I want to create a crawlable AJAX feature using jQuery. I previously used jQuery Ajax on my website for searching, but nothing was indexed. Here is my new approach: <a href="www.example.com/page1" id="linkA">page 1</a> I display the results ...

Live server feature in Visual Studio Code is not able to update CSS styles

Here's the problem: I'm encountering a CSS styling issue with the Live Server extension in Visual Studio Code (by ritwickdey). When I launch the live preview, none of my CSS styles are being applied. Although the HTML displays correctly, the CSS ...

Is there a way to automatically increase a value by clicking on it?

Check out this code snippet I'm working with: let funds = document.createElement('funds') funds.style.color = 'green' funds.style.textAlign = 'center' funds.style.fontSize = '50px' funds.style.backgroundCol ...

Does an href and click events both happen simultaneously?

JavaScript Purpose: Implement a series of loops and create anchor links with the 'href' attribute <a class="mui-control-item" v-for="(item, index) in dai" v-on:click ="abc(item)" :href="'#item'+(index+1)+ 'mobile'" ...

Convert an array into a JSON object for an API by serializing it

Currently, I am working with Angular 12 within my TS file and have encountered an array response from a file upload that looks like this- [ { "id": "7", "name": "xyz", "job": "doctor" ...

VueJS functions properly on Google Chrome, however it may encounter compatibility issues when using

I am currently working on a VueJs app resembling an auction, with the backend powered by Laravel. Everything runs smoothly when I test it on Chrome, but for some reason, Safari seems to be giving me trouble. The app consists of two main components: Deale ...

Utilizing Express-Partials in conjunction with a single layout to incorporate multiple partials

Recently, as I migrated to Node.js and ExpressJS 3.0, I noticed that partials were no longer supported. However, I stumbled upon express-partials which provided a similar feature. Upon exploring the example on their GitHub page, I came across this snippet ...

Trouble with setting state in React using hooks

There appears to be an issue with the code below where the variable newName's state is not changing as expected. import React, { useState } from 'react' const App = () => { const [ persons, setPersons] = useState([ { name: & ...

Utilizing ScrollView Component in React Native

I have developed a simple app that displays a collection of images with titles, resembling a film gallery where all available films can be viewed. However, I encountered an issue when trying to implement the ScrollView element as it does not allow for scro ...

Vue.js does not display HTML properly within the vue-swal component

I'm currently working on integrating HTML content into a Sweet Alert popup using this code snippet Link: https://www.npmjs.com/package/vue-swal this.$swal({ title: '<i>Custom HTML</i>', html:`This is an <em> em ...

What is the inability to place a div that is 30% wide alongside another div that is 70% wide, and keep them in a horizontal line?

If I make a div that is 30% wide, and another div that is 70% wide, they do not align horizontally. To fix this, I need to ensure that the combined widths of the two divs are less than 100%. Here's an example of how it can be done: <div id="wrapp ...

Implementing HTML tags in C# code

Below is an example of HTML script: <h1> This is heading one </h1> <p> This is paragraph. </p> I would appreciate any recommendations on how to add <html></html> tags to the above script using C#. ...

What should we do to resolve the uncommon use of the 'this' es-lint error? Which rule should we disable?

Recently, I encountered an issue with my Nuxt setup that is configured with el-lint and prettier. Every time I try to use 'this' within my template, it throws up an error unexpectedly. 6:15 error Unexpected usage of 'this' vue/this ...

Unable to match the array of objects based on the specified key indicator

Can someone help me understand how to map an array of objects using the code snippet below? {posts.map((post) => { <PostList id={post.id} key={post.id} username={post?.data?.username} ...

Turn off the scrollbar without losing the ability to scroll

Struggling with disabling the HTML scrollbar while keeping the scrolling ability and preserving the scrollbar of a text area. Check out my code here I attempted to use this CSS: html {overflow:hidden;} Although it partially worked, I'm not complete ...

Position the table at the bottom of the page using CSS

I'm experiencing an issue where my HTML is not rendering correctly. I need to move the table with the ID "footer" to the bottom of the page. Here's the structure of the situation: <div id="container"> <table id="footer"></tabl ...

The hook call at the Material UI TextField component is not valid

Hello, I am currently working on a personal project and encountering a delay due to the following error message: react-refresh-runtime.development.js:315 Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component ...

Guide on adding the .html extension to your URL in Nextjs

In my Nextjs 13.5.2 page directory setup, I am facing a requirement to add ".html" to the URL for SEO purposes on Baidu. For instance: www.test.com/news/123 -> www.test.com/news/123.html I have attempted the following: Renaming the filename to [slug].ht ...

What method sits snugly between prepend() and append()?

Just a quick question I have. I am attempting to align an element with my target. Usually, we use prepend (before the target) and append (after the target). Is there something similar that allows us to position that element directly on top of what we are ...

Error in Babel-Loader when executing npm run build

Not being a webpack expert, I decided to upgrade from V3 to V4. After fixing the depreciation errors in my webpack config, I hit a roadblock with a syntax error from babel-loader: Module build failed (from ./node_modules/babel-loader/lib/index.js): ...