As the title says I need to be able to convert the table into a pdf with a header across multiple pages (just like I have it doing in print).
I've found several sources on how to convert react components to a pdf file. But none cover the combination of requiring a component/table spread across multiple pages and importing the CSS you have too. I have it working for print using the react-to-print Library, but I can't seem to find anything for a pdf. The react-pdf library forms stays you cannot use html elements with it.
full code - https://codesandbox.io/s/react-table-to-pdf-m15em?file=/src/App.js
The pdf function...
exportPdf = () => {
const state = this.props.listOfStates.find(state => state.id === this.state.selectedStateId);
const school = this.props.listOfSchools.find(school => school.id === this.state.selectedSchoolId);
Promise.resolve(this.setState({ ...this.state, selectedStateNamePdf: state.stateName, selectedSchoolNamePdf: school.schoolName }))
.then(() => {
const input = document.getElementById('pdf-element');
html2canvas(input)
.then((canvas) => {
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF();
pdf.addImage(imgData, 'JPEG', 0, 0);
pdf.addPage();
pdf.addImage(imgData, 'JPEG', 0, 0);
pdf.save("download.pdf");
})
;
})
}
The pdf component...
class PdfReportContent extends Component {
render(){
const { selectedReportDetails, stateName, schoolName, startDate, endDate } = this.props;
return (
<div id="pdf-element" style={{maxWidth: "210mm", width: "100%", height: "100%", position: "relative", margin: "0"}}>
<div style={{display: "block"}}>
<div style={{width: "100%", display: "flex", justifyContent: "space-between", padding: "1vh 2.5vh 0"}}>
<div>
<h2 className="header-title-one">SCHOOL</h2>
<h2 className="header-title-two">REPORT</h2>
</div>
<div style={{display: "flex"}}>
<div style={{display: "inline-block", textAlign: "right"}}>
<h5>{stateName}</h5>
<h5>{schoolName}</h5>
<p>{startDate} - {endDate}</p>
</div>
</div>
</div>
<hr />
<h3 style={{margin: "10px 0 0 2.5vh"}}>REPORT RESULTS</h3>
</div>
<div id="print-list-body">
{selectedReportDetails.map((classDetails, indexOne) =>
<div key={indexOne} style={{maxWidth: "200mm", width: "100%", margin: "40px auto 0 auto", boxSizing: "border-box"}}>
<h2 style={{marginBottom: "10px", color: "#01A3E0"}}>{classDetails.className}</h2>
{classDetails.classes.map((dateTable, indexTwo, classes) =>
<table key={indexTwo} className="tbl-reports-list">
<tbody>
<tr>
<th>{dateTable.date}</th>
<th>Students</th>
<th>Grades</th>
<th>Assignment</th>
<th>Attendance</th>
</tr>
{dateTable.instructors.map((instructor, indexThree, instructorRows) =>
instructor.students.map((row, indexFour, studentRows) =>
indexTwo === classes.length-1 ?
<tr key={indexFour} style={indexFour === studentRows.length-1 ? { borderBottom: "2px solid #01A3E0"} : {}}>
{indexFour === 0 ?
<td>
<h5>{instructor.instructorName}</h5>
</td> : <td />
}
<td style={{backgroundColor: "#ffffff"}}>{row.name}</td>
<td style={row.isHonorStudent ? {backgroundColor: "#ffffff"} : {backgroundColor: "#ffedbc"}}>{row.grade}</td>
<td style={{backgroundColor: "#ffffff"}}>{row.assignment}</td>
<td style={{backgroundColor: "#ffffff"}}>{row.attendance}</td>
</tr> :
<tr key={indexFour} style={indexFour === studentRows.length-1 && indexThree !== instructorRows.length-1 ? { borderBottom: "2px solid #01A3E0"} : {}}>
{indexFour === 0 ?
<td>
<h5>{instructor.instructorName}</h5>
</td> : <td />
}
<td style={{backgroundColor: "#ffffff"}}>{row.name}</td>
<td style={row.isHonorStudent ? {backgroundColor: "#ffffff"} : {backgroundColor: "#ffedbc"}}>{row.grade}</td>
<td style={{backgroundColor: "#ffffff"}}>{row.assignment}</td>
<td style={{backgroundColor: "#ffffff"}}>{row.attendance}</td>
</tr>
)
)}
</tbody>
</table>
)}
</div>
)}
</div>
</div>
);
}
}
Steps to reproduce issue:
- Select any items in both the dropdowns
- Click Generate Report
- Click Download PDF
- Open pdf and notice how the first and second page show the same thing, and the rest of the table data is missing.
If anyone can fork the project in the codesandbox link and show me what I'm missing it would be much appreciated.