使用 React 未处理的拒绝(错误)创建 Pdf:在结束后写入
Create Pdf Using React Unhandled Rejection (Error): write after end
描述错误
大家好,
我正在尝试生成包含一些 user-provided 信息的 PDF。特别是,我希望我的用户选择 pdf 的文件名,这也是它的标题。
为此,我使用:
"@react-pdf/renderer": "^1.6.12" for the pdf rendering
"react-bootstrap": "^1.3.0" for the page layout
"formik": "^2.2.0" for form management
我遇到的问题在于,每当用户开始在适当的输入中输入所需的 filename/title 时,页面就会崩溃并出现以下错误:
Unhandled Rejection (Error): write after end
3 stack frames were expanded.
writeAfterEnd
node_modules/stream-browserify/node_modules/readable-stream/lib/_stream_writable.js:288
(anonymous function)
node_modules/stream-browserify/node_modules/readable-stream/lib/_stream_writable.js:332
addContent
node_modules/@react-pdf/pdfkit/dist/pdfkit.browser.es.js:4184
经过更深入的调查,我注意到问题出在生成的 pdf 内容的“动态性”上。
代码如下:
const DownloadModal = ({configuration}) => {
const [show, setShow] = useState(false);
const formik = useFormik({
initialValues: {
name: "",
}
});
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<Button variant="primary"
onClick={() => {
handleShow()
}}
>
Download PDF <DownloadIcon/>
</Button>
<Modal size={"lg"} show={show} onHide={handleClose} animation={true}>
<Modal.Header closeButton>
<Modal.Title>Choose filename</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form onSubmit={(event) => {
event.preventDefault();
}}>
<Form.Group as={Row}>
<Form.Label column sm={2}>
Filename
</Form.Label>
<Col sm={10}>
<InputGroup className="mb-3">
<FormControl
type="text"
id={"name"}
name={"name"}
placeholder="filename"
onChange={formik.handleChange}
value={formik.values.name}
autoComplete={"off"}
/>
<InputGroup.Append>
<InputGroup.Text id="basic-addon2">.pdf</InputGroup.Text>
</InputGroup.Append>
</InputGroup>
</Col>
</Form.Group>
</Form>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<DownloadPDFButton
data={configuration}
title={formik.values.name}
/>
</Modal.Footer>
</Modal>
</>
);
};
const DownloadPDFButton = ({data, title}) => {
return (
<PDFDownloadLink
document={
<PdfDocument
data={data}
title={{title}}
/>}
fileName={`${title}.pdf`}
className={"btn btn-link"}
>
{({blob, url, loading, error}) =>
loading ? <Spinner animation="border" variant="primary"/> : "Download"
}
</PDFDownloadLink>
)
}
我认为问题出在我显示的方式上 title.title
。但是我真的找不到办法让它工作。
const Title = ({title}) => {
return (
<View style={styles.titleContainer}>
<Text>{title.title}</Text>
</View>
)
}
;
const PdfDocument = (props) => {
const configurationData = {
plant: props.data.plant,
flow: props.data.flow,
optionals: props.data.optionals
};
const utilitiesData = {
total_installed_power: props.data.total_installed_power,
total_absorbed_power: props.data.total_absorbed_power,
makeup_water: props.data.makeup_water,
compressed_air: props.data.compressed_air
};
return (
<Document>
<Page key={"page-0"} style={styles.page}>
<Image style={styles.logo} src={logo}/>
<Title title={props.title}/>
<ConfigurationPDF configuration={configurationData}/>
<ResultsPDF results={utilitiesData}/>
</Page>
</Document>
);
};
先谢谢大家!!
运行环境:
- OS: [MacOS]
- 浏览器[chrome、野生动物园]
我想你的问题现在已经解决了
我只把formik state
转换成react state
Codesandbox:https://codesandbox.io/s/reverent-browser-1bn4n
描述错误
大家好, 我正在尝试生成包含一些 user-provided 信息的 PDF。特别是,我希望我的用户选择 pdf 的文件名,这也是它的标题。 为此,我使用:
"@react-pdf/renderer": "^1.6.12" for the pdf rendering "react-bootstrap": "^1.3.0" for the page layout "formik": "^2.2.0" for form management
我遇到的问题在于,每当用户开始在适当的输入中输入所需的 filename/title 时,页面就会崩溃并出现以下错误:
Unhandled Rejection (Error): write after end
3 stack frames were expanded.
writeAfterEnd
node_modules/stream-browserify/node_modules/readable-stream/lib/_stream_writable.js:288
(anonymous function)
node_modules/stream-browserify/node_modules/readable-stream/lib/_stream_writable.js:332
addContent
node_modules/@react-pdf/pdfkit/dist/pdfkit.browser.es.js:4184
经过更深入的调查,我注意到问题出在生成的 pdf 内容的“动态性”上。
代码如下:
const DownloadModal = ({configuration}) => {
const [show, setShow] = useState(false);
const formik = useFormik({
initialValues: {
name: "",
}
});
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<Button variant="primary"
onClick={() => {
handleShow()
}}
>
Download PDF <DownloadIcon/>
</Button>
<Modal size={"lg"} show={show} onHide={handleClose} animation={true}>
<Modal.Header closeButton>
<Modal.Title>Choose filename</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form onSubmit={(event) => {
event.preventDefault();
}}>
<Form.Group as={Row}>
<Form.Label column sm={2}>
Filename
</Form.Label>
<Col sm={10}>
<InputGroup className="mb-3">
<FormControl
type="text"
id={"name"}
name={"name"}
placeholder="filename"
onChange={formik.handleChange}
value={formik.values.name}
autoComplete={"off"}
/>
<InputGroup.Append>
<InputGroup.Text id="basic-addon2">.pdf</InputGroup.Text>
</InputGroup.Append>
</InputGroup>
</Col>
</Form.Group>
</Form>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<DownloadPDFButton
data={configuration}
title={formik.values.name}
/>
</Modal.Footer>
</Modal>
</>
);
};
const DownloadPDFButton = ({data, title}) => {
return (
<PDFDownloadLink
document={
<PdfDocument
data={data}
title={{title}}
/>}
fileName={`${title}.pdf`}
className={"btn btn-link"}
>
{({blob, url, loading, error}) =>
loading ? <Spinner animation="border" variant="primary"/> : "Download"
}
</PDFDownloadLink>
)
}
我认为问题出在我显示的方式上 title.title
。但是我真的找不到办法让它工作。
const Title = ({title}) => {
return (
<View style={styles.titleContainer}>
<Text>{title.title}</Text>
</View>
)
}
;
const PdfDocument = (props) => {
const configurationData = {
plant: props.data.plant,
flow: props.data.flow,
optionals: props.data.optionals
};
const utilitiesData = {
total_installed_power: props.data.total_installed_power,
total_absorbed_power: props.data.total_absorbed_power,
makeup_water: props.data.makeup_water,
compressed_air: props.data.compressed_air
};
return (
<Document>
<Page key={"page-0"} style={styles.page}>
<Image style={styles.logo} src={logo}/>
<Title title={props.title}/>
<ConfigurationPDF configuration={configurationData}/>
<ResultsPDF results={utilitiesData}/>
</Page>
</Document>
);
};
先谢谢大家!!
运行环境:
- OS: [MacOS]
- 浏览器[chrome、野生动物园]
我想你的问题现在已经解决了
我只把formik state
转换成react state
Codesandbox:https://codesandbox.io/s/reverent-browser-1bn4n