Search code examples
reactjsblobpdf-generationreact-pdfreact-pdfrenderer

How to break a page conditionally with react-pdf/renderer


I am trying to add a page break conditionally once my Section title is not on the first page, i.e., page breaks should begin after the second page. How do I add this condition to my View tag for the "Section Title" to my code below where there is break property should be applied from the 2nd page?

IMPORTANT: This code is not a React component. This code is a function that is called when a button is clicked from a different react component. The GeneratePDF is added to an onClick property; when a person clicks the button, the pdf will be generated.

I am using react-pdf/renderer. Please see my code below, where the page break starts from page 1.

GeneratePDF.jsx

import { saveAs } from 'file-saver';
import { pdf, Document, Page, Text, View, Image } from '@react-pdf/renderer';
import styles from './styles';

const GeneratePDF = async (fileName, data) => {
  const blob = await pdf((
    <Document>
      <Page style={styles.body}>
        <View style={styles.root}>
          <Text style={styles.headerTitle}>
            Header Title
          </Text>
          <Image
            style={styles.image}
            src="someImage.jpg"
          />
        </View>

        {data.map((item, index) => (
          <View key={item}>
            <View break wrap={false}>
              <Text style={styles.sectionTitle}>Section Title</Text>
            </View>
            <View wrap={false}>
              <Text style={styles.subtitle}>About</Text>
              <Text style={styles.aboutDesc}>{item.description}</Text>
            </View>
            <View>
              <Text>{'\n'}</Text>
              <Text style={styles.subtitle}>Things wanted</Text>
              {item.things.map((thing, idx) => (
                <Text key={thing} style={styles.list}>
                  -
                  {thing.description}
                </Text>
              ))}
            </View>
          </View>
        ))}

        <Text
          style={styles.pageNumber}
          render={({ pageNumber, totalPages }) => (
            `${pageNumber} / ${totalPages}`
          )}
          fixed
        />
      </Page>
    </Document>
  )).toBlob();
  
  saveAs(blob, fileName);
};

export default GeneratePDF;


Solution

  • The simplest way to do this was, since I wanted each new SectionTitle on a new page, this is the way I did it using the index from the map, break={index > 0}. This ensures that my page break starts only from the 2nd item.

            {data.map((item, index) => (
              <View key={item}>
                <View break={index > 0} wrap={false}>
                  <Text style={styles.sectionTitle}>Section Title</Text>
                </View>
                ...
              </View>
            ))}