I am developing a small CRM (using React for the frontend) and one of the pages is connected to a database that stores information about all the works made from technicians for different customers. Each row of my table stores has four fields (date of the work, begin and end time and notes).
Data shown in my web app should be exported to PDF, so I am using React PDF library to generate a PDF document. Each row should adjust its height according to the text written in all the fields of that row, and this is true for the firsts pages.
But here comes the problem: I am using attribute wrap={false} for each <View> tag that represents a row of my database: in this way, if the row doesn’t have enough space, it should be rendered in the next page. But when a row is rendered in the following page, the height of the row seems to be “fixed” and doesn’t take into consideration the text written into the row
Please note that the PDF has also a small footer with the “fixed” attribute, I don’t know if this could be part of the problem
I have also activated the native debug mode for the views that show data: those views also have a 2px solid purple border
Here is my full code:
const summaryData = [
{}
]
const columns = [
{ name: "date", text: "date", state: true, flex: '2' },
{ name: "begin", text: "begin", state: true, flex: '1' },
{ name: "end", text: "end", state: true, flex: '1' },
{ name: "notes", text: "notes", state: true, flex: '1' }
]
const dbData = [
{ date: "2024-04-05", begin: "08:00", end: "10:00", notes: "here it goes some really long text that must be shown inside of a 'row view' (the one with purple border) " },
{ date: "2024-04-05", begin: "08:00", end: "10:00", notes: "here it goes some really long text that must be shown inside of a 'row view' (the one with purple border) " },
{ date: "2024-04-05", begin: "08:00", end: "10:00", notes: "here it goes some really long text that must be shown inside of a 'row view' (the one with purple border) " },
{ date: "2024-04-05", begin: "08:00", end: "10:00", notes: "here it goes some really long text that must be shown inside of a 'row view' (the one with purple border) " },
{ date: "2024-04-05", begin: "08:00", end: "10:00", notes: "here it goes some really long text that must be shown inside of a 'row view' (the one with purple border) " },
{ date: "2024-04-05", begin: "08:00", end: "10:00", notes: "here it goes some really long text that must be shown inside of a 'row view' (the one with purple border) " },
{ date: "2024-04-05", begin: "08:00", end: "10:00", notes: "here it goes some really long text that must be shown inside of a 'row view' (the one with purple border) " },
{ date: "2024-04-05", begin: "08:00", end: "10:00", notes: "here it goes some really long text that must be shown inside of a 'row view' (the one with purple border) " },
{ date: "2024-04-05", begin: "08:00", end: "10:00", notes: "here it goes some really long text that must be shown inside of a 'row view' (the one with purple border) " },
{ date: "2024-04-05", begin: "08:00", end: "10:00", notes: "here it goes some really long text that must be shown inside of a 'row view' (the one with purple border) " },
]
const Footer = () => {
return <View style={[styles.section, { position: 'absolute', left: '20px', right: '20px', bottom: '3%' }]} fixed>
<View style={[styles.riga, { display: 'flex', justifyContent: 'center', width: '100%' }]}>
<Text>Company name</Text>
<Text>, company address</Text>
</View>
<View style={{ marginTop: '8px', display: 'flex', flexDirection: 'row', width: '100%', justifyContent: 'space-between' }}>
<View style={styles.riga}>
<Text>File</Text>
<Text>: NomeFile.pdf</Text>
</View>
<Text style={styles.pageNumber} render={({ pageNumber, totalPages }) => (
`${pageNumber} di ${totalPages}`
)} />
</View>
</View>
}
const Quixote = () => (
<Document>
<Page style={styles.page}>
<View style={{ flex: '1', width: '100%', border: '2px solid orange' }} id='main'>
<View style={[styles.section, { marginTop: '15px' }]} id='dettaglio'>
<Text style={[styles.titoloSezione]}>DETTAGLIO</Text>
<View id='righe' style={{ marginTop: '15px' }}>
<View style={[styles.riga, styles.bordoRiga]}>
{
columns.filter(column => column.state).map((intestazione, key) => (
<View key={key} style={[styles.headerEl, styles.singleEl, { flex: intestazione.flex ? intestazione.flex : '1' }]}>
<Text>{intestazione.text}</Text>
</View>
))
}
</View>
{
dbData && Array.isArray(dbData) && dbData.map((oggetto, key, array) => {
return (
<View key={key} debug style={[styles.riga, { border: '2px solid purple' }]} wrap={false}>
{
columns.filter(column => column.state).map((colonna, campoIndex) => (
<Text key={campoIndex} style={[styles.singleEl, { flex: colonna.flex, border: '1 px solid green', height: 'auto' }]}>
{oggetto[colonna.name] !== null ? oggetto[colonna.name] : ''}
</Text>
))
}
</View>
);
})
}
</View>
</View>
<View style={[styles.section, { marginTop: '15px' }]} id='esportato'>
<View style={styles.riga}>
<Text>Exported in date: </Text>
<Text>dd/mm/yyyy hh:mm</Text>
</View>
</View>
</View>
<Footer></Footer>
</Page>
</Document>
);
Font.register({
family: 'Oswald',
src: 'https://fonts.gstatic.com/s/oswald/v13/Y_TKV6o8WovbUd3m_X9aAA.ttf'
});
const styles = StyleSheet.create({
bordoRiga: {
borderBottom: '1px solid #c7c7c7'
},
singleEl: {
display: 'block',
height: 'auto',
marginRight: '2px'
},
footer: {
position: 'absolute',
bottom: 5,
left: 0,
right: 0,
border: '2px solid red'
},
section: {
color: 'black',
width: '100%',
height: 'auto',
display: 'flex',
flexDirection: 'column'
},
riga: {
display: 'flex',
flexDirection: 'row',
paddingVertical: '2px'
},
titoloSezione: {
border: '2px solid red'
},
page: {
paddingTop: 30,
paddingBottom: 70,
paddingHorizontal: 35,
},
title: {
fontSize: 24,
textAlign: 'center',
fontFamily: 'Oswald'
},
author: {
fontSize: 12,
textAlign: 'center',
marginBottom: 40,
},
subtitle: {
fontSize: 18,
margin: 12,
fontFamily: 'Oswald'
},
text: {
margin: 12,
fontSize: 14,
textAlign: 'justify',
fontFamily: 'Times-Roman'
},
image: {
marginVertical: 15,
marginHorizontal: 100,
},
header: {
fontSize: 12,
marginBottom: 20,
textAlign: 'center',
color: 'grey',
},
pageNumber: {
fontSize: 12,
textAlign: 'center',
color: 'grey',
},
});
ReactPDF.render(<Quixote />);
There are some css classes that are not used and the general style looks awful, but that’s not the point of my question.
Note that you can try my code directly online at this link: https://react-pdf.org/replYou just have to open the editor, clear all the code and copy what I have given in this question. If you decide to try it in this way, I have already replaced database with some mock data, so everything on the “backend” should already be fine.
Also, with these specific data, the issues seems to appear only in the last page. However, I am pretty sure that it could occur also on pages in the middle (e.g: page 2 of 3), but not on the first page (because if a component is rendered in the first page we can be sure that the wrap attribute didn’t come in action)
Leonardo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.