简体   繁体   中英

react-pdf from ByteArray response?

I am trying to request a PDF file from my java server through a react typescript app. Then trying to display this byte[] through react-pdf.

The request to the server looks like this:

const [invoice, setInvoice] = React.useState<any>()   

 const downloadPdf = (theInvoice: Invoice) => {
        store.app.cubaRest?.invokeService<any>('billing_InvoiceService', 'generateInvoiceDocument', { invoice: theInvoice })
            .then((response: any) => {
                console.log(response)
                let array= JSON.parse(response).content
                setInvoice(array)             
            }).finally(()=>{                
            })    
        }

 if (invoice) {
        console.log("there is invoice")
        return (
            <div>
                <Document
                    file={{ data: invoice }}
                    onLoadSuccess={onDocumentLoadSuccess}
                    onLoadError={console.error}
                >
                    <Page pageNumber={pageNumber} />
                </Document>
            </div>

The console log from the raw "response" above looks like this:

{"report":{"_entityName":"report$Report","id":"1dd6746f-3580-6e3c-3aa6-e3f5db0a290b","code":"default-invoice","roles":[],"defaultTemplate":{"id":"0de287de-1931-a375-d10f-70ae431a3ca7","content":"PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLSBDcmVhdGVkIHdpdGggSmFzcGVyc29mdCBTdHVkaW8gdmVyc2lvbiA2LjE2LjAuZmluYWwgdXNpbmcgSmFzcGVyUmVwb3J0cyBMaWJyYXJ5IHZlcnNpb24gNi4xNi4wLTQ4NTc5ZDkwOWI3OTQzYjY0NjkwYzY1YzcxZTA3ZTBiODA5ODE5MjggIC0tPgo8amFzcGVyUmVwb3J0IHhtbG5zPSJodHRwOi8vamFzcGVycmVwb3J0cy5zb3VyY2Vmb3JnZS5uZXQvamFzcGVycmVwb3J0cyIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vamFzcGVycmVwb3J0cy5z .......

When I set the state from the response the page just keeps rerendering and the pdf does not show. Presumably it is doing a re-render for every byte in the byte array.

Not sure how to resolve this. Also not sure if I am sending the byte[] correctly to setInvoice either. Or if the byteArray is in the correct format for that matter.

Was quite a simple solution.

instead of:

let array= JSON.parse(response).content
            setInvoice(array)    

do:

setInvoice({data: JSON.parse(response).content});

 if (invoice) {
    return (
        <div>
            <Document
                file={invoice}
                onLoadSuccess={onDocumentLoadSuccess}
                onLoadError={console.error}
            >
                <Page pageNumber={pageNumber} />
            </Document>

        </div>

Heres the base64 approach

1. Given base64 string of the pdf file

const fileAsBase64 = || YOUR PDF FILE IN BASE64 AS STRING ||

2. Convert base64 string to bytearray

export const base64ToArrayBuffer = (base64) => {
const binaryString = window.atob(base64); // Comment this if not using base64
const bytes = new Uint8Array(binaryString.length);
return bytes.map((byte, i) => binaryString.charCodeAt(i));
}

3. Add the byearray to component by calling above function

 <Document file={{ data :base64ToArrayBuffer(base64)}}/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM