Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it easier to display all pages #346

Closed
2 tasks done
wojtekmaj opened this issue Feb 4, 2019 · 10 comments
Closed
2 tasks done

Make it easier to display all pages #346

wojtekmaj opened this issue Feb 4, 2019 · 10 comments
Labels
enhancement New feature or request

Comments

@wojtekmaj
Copy link
Owner

Before you start - checklist

  • I understand that React-PDF does not aim to be a fully-fledged PDF viewer and is only a tool to make one
  • I have checked if this feature request is not already reported

Is your feature request related to a problem? Please describe.

It should be easy to display all PDF pages at once, as suggested in #98.

Describe the solution you'd like

<AllPages /> component? Better documentation? Optional render props that allows to iterate through all pages?

@wojtekmaj wojtekmaj added the enhancement New feature or request label Feb 4, 2019
@qaisershehzad
Copy link

Hello @wojtekmaj , Any chance with this component to display all pages ?

thanks.

@wojtekmaj
Copy link
Owner Author

@qaisershehzad Not right now. Busy in private life, and with budget of $0 I need to prioritize to make a living :)

@qaisershehzad

This comment has been minimized.

@wojtekmaj
Copy link
Owner Author

After consideration I've decided not to put this AllPages component into core React-PDF. Here's why:

Including well built, performant AllPages component would require building a solution using third party tools like React-Window. This would likely cause developers to use AllPages instead of whatever solutions they are already using for lazy loading components. Building AllPages component that would work well with React-Window and other similar libraries would be super hard, if not impossible to do.

I'll be more than happy to see React-PDF based extensions, which use react-pdf API to provide additional functionalities.

Here's <AllPages /> implementation, without any external libraries which would delay loading pages until it's needed, that you can base your work on:

import React, { PureComponent } from 'react';

import DocumentContext from 'react-pdf/dist/DocumentContext';
import { PageInternal } from 'react-pdf/dist/Page';

export class AllPagesInternal extends PureComponent {
  componentDidMount() {
    const { pdf } = this.props;

    if (!pdf) {
      throw new Error('Attempted to load a page, but no document was specified.');
    }
  }

  render() {
    const { pdf } = this.props;

    const { numPages } = pdf;

    return (
      Array.from(
        new Array(numPages),
        (el, index) => (
          <PageInternal
            {...this.props}
            key={`page_${index + 1}`}
            pageNumber={index + 1}
          />
        ),
      )
    );
  }
}


const { pageIndex, pageNumber, ...allPagesInternalPropTypes } = PageInternal.propTypes;

AllPagesInternal.propTypes = {
  ...allPagesInternalPropTypes,
};

const AllPages = props => (
  <DocumentContext.Consumer>
    {context => (
      <AllPagesInternal
        {...context}
        {...props}
        // For backwards compatibility
        renderAnnotationLayer={
          typeof props.renderAnnotationLayer !== 'undefined'
            ? props.renderAnnotationLayer
            : props.renderAnnotations
        }
      />
    )}
  </DocumentContext.Consumer>
);

export default AllPages;

As you can see, render function is just an array based on numPages, which we then map on. This makes it rather easy to make it work with React-Window or React-Virtualized.

@amyhuangxbd
Copy link

I think AllPages is quite necessary, many other file like ppt,excel can be transffed to be pdf, they should be display multi pages.

@amyhuangxbd

This comment has been minimized.

@ashnakumar
Copy link

After consideration I've decided not to put this AllPages component into core React-PDF. Here's why:

Including well built, performant AllPages component would require building a solution using third party tools like React-Window. This would likely cause developers to use AllPages instead of whatever solutions they are already using for lazy loading components. Building AllPages component that would work well with React-Window and other similar libraries would be super hard, if not impossible to do.

I'll be more than happy to see React-PDF based extensions, which use react-pdf API to provide additional functionalities.

Here's <AllPages /> implementation, without any external libraries which would delay loading pages until it's needed, that you can base your work on:

import React, { PureComponent } from 'react';

import DocumentContext from 'react-pdf/dist/DocumentContext';
import { PageInternal } from 'react-pdf/dist/Page';

export class AllPagesInternal extends PureComponent {
  componentDidMount() {
    const { pdf } = this.props;

    if (!pdf) {
      throw new Error('Attempted to load a page, but no document was specified.');
    }
  }

  render() {
    const { pdf } = this.props;

    const { numPages } = pdf;

    return (
      Array.from(
        new Array(numPages),
        (el, index) => (
          <PageInternal
            {...this.props}
            key={`page_${index + 1}`}
            pageNumber={index + 1}
          />
        ),
      )
    );
  }
}


const { pageIndex, pageNumber, ...allPagesInternalPropTypes } = PageInternal.propTypes;

AllPagesInternal.propTypes = {
  ...allPagesInternalPropTypes,
};

const AllPages = props => (
  <DocumentContext.Consumer>
    {context => (
      <AllPagesInternal
        {...context}
        {...props}
        // For backwards compatibility
        renderAnnotationLayer={
          typeof props.renderAnnotationLayer !== 'undefined'
            ? props.renderAnnotationLayer
            : props.renderAnnotations
        }
      />
    )}
  </DocumentContext.Consumer>
);

export default AllPages;

As you can see, render function is just an array based on numPages, which we then map on. This makes it rather easy to make it work with React-Window or React-Virtualized.

How to link pdf file? It is throwing an Error: Attempted to load a page, but no document was specified.

@wojtekmaj
Copy link
Owner Author

@ashnakumar Looks like you may have not wrapped your AllPages component in Document component.

@ashnakumar
Copy link

I didnt understand

@ashnakumar Looks like you may have not wrapped your AllPages component in Document component.

@biennui1998mu
Copy link

biennui1998mu commented Mar 8, 2024

import {FixedSizeList as List} from 'react-window'

import DocumentContext from 'react-pdf/dist/esm/DocumentContext';
import { PageInternal } from 'react-pdf/dist/esm/Page';

export class AllPagesInternal extends PureComponent {
    componentDidMount() {
        console.log("sonnn", this.props);
        const { pdf } = this.props;

        if (!pdf) {
            throw new Error('Attempted to load a page, but no document was specified.');
        }
    }

    render() {
        const { pdf } = this.props;

        const { numPages } = pdf;

        const Row = ({index, style}) => {
            return (
                <PageInternal
                    {...this.props}
                    key={`page_${index + 1}`}
                    pageNumber={index + 1}
                />
            )
        };
        
        return (
            <List
                itemCount={numPages}
                itemSize={this.props.height}
                width={this.props.width}
                height={this.props.height * numPages}
            >
                {Row}
            </List>
        );
    }
}


const { pageIndex, pageNumber, ...allPagesInternalPropTypes } = PageInternal.propTypes;

AllPagesInternal.propTypes = {
    ...allPagesInternalPropTypes,
};

const AllPages = props => (
    <DocumentContext.Consumer>
        {context => (
            <AllPagesInternal
                {...context}
                {...props}
                // For backwards compatibility
                renderAnnotationLayer={
                    typeof props.renderAnnotationLayer !== 'undefined'
                        ? props.renderAnnotationLayer
                        : props.renderAnnotations
                }
            />
        )}
    </DocumentContext.Consumer>
);

export default AllPages;

I tried AllPages with react-window but my console log in componentDidMount was infinity re-render. Can you demo an example of how to use AllPages with react-window or react-virtualize or check where is code wrong? @wojtekmaj

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants