Search code examples
javascriptreactjsreact-pdf

Attempting to create a dynamic react pdf report generator based on params


Code below: codesandbox.io/s/muddy-monad-zqwt73?file=/src/App.js

Currently, unsure why, the pages are not making it into the document and an empty Document is rendered.

I am unsure why. To me, this reads as I have created page elements, placed them in a list, and I should be able to map through and render all the pages to the Document. I am unsure why it is not working.

EDIT

As per suggestion, I changed the code to look as follows:

const styles = StyleSheet.create({
  header: {
    flexDirection: 'row',
    textAlign: 'left',
    fontSize: '30px',
    fontFamily: 'SF Pro Text',
    marginBottom: '25px',
    marginTop: '30px',
    marginLeft: '30px',
    justifyContent: 'space-evenly'
  }
})


class DavidPDF extends Component {
  constructor(name, params) {
    super(name, params);
    this.name = name;
    this.params = params;
    this.content = [];
  }

  buildPages() {
    console.log("building")
    for (let i = 0; i < this.params.length; i += 1) {
      console.log(i)
      let jsxPage = this.buildPage(this.params[i])
      this.content.push(jsxPage)
    }
  }

  buildPage(pageParams) {
    console.log("building indv page")
    const pageName = pageParams.pageName;
    const viewParams = pageParams.views;
    const pageViewParams = [];

    for (let i = 0; i < viewParams.length; i += 1) {
      let view = this.buildView(viewParams[i]);
      pageViewParams.push(view);
    }

    return (
      <Page>
        <View>{pageName}</View>
      </Page>
    )
  }

  buildView(viewParams) {
    if (viewParams.viewType == "headerText") {
      const text = viewParams.text;
      return (
        <View>
          <Text style={styles.header}>
            {text}
          </Text>
        </View>
      )
    }
  }
  render() {
    console.log("rendering")
    this.buildPages(this.params)
    console.log(this.content)
    return (
      <Document>
        {this.content}
      </Document>
    )
  }
}

function Test() {

  const pagesInfo = [
    {
      pageName: "Xtina's Page",
      views: [
        {
          viewType: "headerText",
          text: "Xtina's page"
        }
      ]
    }
  ]

  let wtf = ["hi2", "hi1", "hi3"]
  const wtfItems = wtf.map((item) => <div>{item}</div>)

  return (
    <div id="first">
      {wtf.map((item) => <div>{item}</div>)}
      <PDFViewer>
        <DavidPDF name="hello" params={pagesInfo} />
      </PDFViewer>
    </div>
  )
}

export default Test;

--- EDIT ----

Hurrah! That error was fixed. Now we have a new one - the pages will not go in.


Solution

  • Instead of approaching it this way, which does not play well, I have switched to generating a page with all my information of interest and adding print css so that a when a user prints (or I print to send to a user), the data is formatted nicely with break points for pages using only css and @media print. I would recommend this strategy to others and am happy to elaborate further if anyone wants!