mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
PDF 渲染优化
This commit is contained in:
parent
7334b8088a
commit
28ee659a2c
@ -14,7 +14,8 @@ order: 24
|
||||
{
|
||||
"type": "pdf-viewer",
|
||||
"id": "pdf-viewer",
|
||||
"src": "/examples/static/simple.pdf"
|
||||
"src": "/examples/static/simple.pdf",
|
||||
"width": 500
|
||||
}
|
||||
```
|
||||
|
||||
@ -38,7 +39,8 @@ order: 24
|
||||
{
|
||||
"type": "pdf-viewer",
|
||||
"id": "pdf-viewer",
|
||||
"name": "file"
|
||||
"name": "file",
|
||||
"width": 500
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -49,6 +51,6 @@ order: 24
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| ---------- | ------ | ------ | ---------- |
|
||||
| src | Api | | 文档地址 |
|
||||
| width | number | 500 | 宽度 |
|
||||
| width | number | | 宽度 |
|
||||
| height | number | - | 高度 |
|
||||
| background | string | #fff | PDF 背景色 |
|
||||
|
@ -16,7 +16,8 @@ export default {
|
||||
{
|
||||
type: 'pdf-viewer',
|
||||
id: 'pdf-viewer',
|
||||
name: 'file'
|
||||
name: 'file',
|
||||
width: 500
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ export interface RendererProps
|
||||
env: RendererEnv;
|
||||
$path: string; // 当前组件所在的层级信息
|
||||
$schema: any; // 原始 schema 配置
|
||||
testIdBuild: TestIdBuilder;
|
||||
testIdBuilder?: TestIdBuilder;
|
||||
store?: IIRendererStore;
|
||||
syncSuperStore?: boolean;
|
||||
data: {
|
||||
|
@ -1,7 +1,8 @@
|
||||
.#{$ns}PdfViewer {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
min-width: 300px;
|
||||
height: 100%;
|
||||
min-height: 500px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 50px 0;
|
||||
@ -14,6 +15,7 @@
|
||||
}
|
||||
|
||||
&-Loading {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
@ -20,15 +20,17 @@ export interface PdfViewerProps extends ThemeProps {
|
||||
width?: number;
|
||||
height?: number;
|
||||
background?: string;
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
const PdfViewer: React.FC<PdfViewerProps> = props => {
|
||||
const {classnames: cx, className, width = 500} = props;
|
||||
const {classnames: cx, className, loading, width = 300} = props;
|
||||
const [file, setFile] = React.useState(props.file);
|
||||
const [loaded, setLoaded] = React.useState(false);
|
||||
const [page, setPage] = React.useState(1);
|
||||
const [scale, setScale] = React.useState(1);
|
||||
const [total, setTotal] = React.useState(1);
|
||||
const wrapper = React.useRef<HTMLDivElement>(null);
|
||||
const inputRef = React.useRef<HTMLInputElement>();
|
||||
|
||||
React.useEffect(() => {
|
||||
@ -67,13 +69,9 @@ const PdfViewer: React.FC<PdfViewerProps> = props => {
|
||||
setScale(scale * t);
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function renderLoading() {
|
||||
return (
|
||||
<div className={cx('PdfViewer-Loading')} style={{width: `${width}px`}}>
|
||||
<div className={cx('PdfViewer-Loading')}>
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
@ -115,27 +113,33 @@ const PdfViewer: React.FC<PdfViewerProps> = props => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cx(className, 'PdfViewer')}>
|
||||
<div className={cx('PdfViewer-Content', {'is-loaded': loaded})}>
|
||||
<Document
|
||||
file={file}
|
||||
onLoadSuccess={handleLoadSuccess}
|
||||
loading={renderLoading()}
|
||||
>
|
||||
<Page
|
||||
className={cx('PdfViewer-Content-Page')}
|
||||
pageNumber={page}
|
||||
width={width}
|
||||
height={props.height}
|
||||
loading={renderLoading()}
|
||||
noData={<div>No PDF data</div>}
|
||||
scale={scale}
|
||||
renderTextLayer={false}
|
||||
renderAnnotationLayer={false}
|
||||
/>
|
||||
</Document>
|
||||
</div>
|
||||
{loaded ? renderTool() : null}
|
||||
<div className={cx(className, 'PdfViewer')} ref={wrapper}>
|
||||
{!file || loading ? (
|
||||
renderLoading()
|
||||
) : (
|
||||
<>
|
||||
<div className={cx('PdfViewer-Content', {'is-loaded': loaded})}>
|
||||
<Document
|
||||
file={file}
|
||||
onLoadSuccess={handleLoadSuccess}
|
||||
loading={renderLoading()}
|
||||
>
|
||||
<Page
|
||||
className={cx('PdfViewer-Content-Page')}
|
||||
pageNumber={page}
|
||||
width={width}
|
||||
height={props.height}
|
||||
loading={renderLoading()}
|
||||
noData={<div>No PDF data</div>}
|
||||
scale={scale}
|
||||
renderTextLayer={false}
|
||||
renderAnnotationLayer={false}
|
||||
/>
|
||||
</Document>
|
||||
</div>
|
||||
{loaded ? renderTool() : null}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -4,7 +4,7 @@
|
||||
* @created: 2024/02/26
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, {Suspense} from 'react';
|
||||
import {
|
||||
autobind,
|
||||
getVariable,
|
||||
@ -40,6 +40,8 @@ export interface PdfViewerProps extends RendererProps {}
|
||||
|
||||
interface PdfViewerState {
|
||||
loading: boolean;
|
||||
inited: boolean;
|
||||
width?: number;
|
||||
}
|
||||
|
||||
export default class PdfViewer extends React.Component<
|
||||
@ -49,14 +51,21 @@ export default class PdfViewer extends React.Component<
|
||||
file?: ArrayBuffer;
|
||||
reader?: FileReader;
|
||||
fetchCancel?: Function;
|
||||
wrapper = React.createRef<HTMLDivElement>();
|
||||
constructor(props: PdfViewerProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
inited: false,
|
||||
loading: false
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.wrapper.current) {
|
||||
this.setState({
|
||||
width: this.wrapper.current.clientWidth - 100
|
||||
});
|
||||
}
|
||||
this.renderPdf();
|
||||
}
|
||||
|
||||
@ -79,6 +88,10 @@ export default class PdfViewer extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.abortLoad();
|
||||
}
|
||||
|
||||
@autobind
|
||||
abortLoad() {
|
||||
if (this.fetchCancel) {
|
||||
@ -117,6 +130,7 @@ export default class PdfViewer extends React.Component<
|
||||
}
|
||||
|
||||
this.setState({
|
||||
inited: true,
|
||||
loading: true
|
||||
});
|
||||
|
||||
@ -140,11 +154,18 @@ export default class PdfViewer extends React.Component<
|
||||
async renderFormFile() {
|
||||
const {name, data} = this.props;
|
||||
const file = getVariable(data, name);
|
||||
this.setState({
|
||||
inited: true,
|
||||
loading: true
|
||||
});
|
||||
if (file instanceof File) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = _e => {
|
||||
const data = reader.result as ArrayBuffer;
|
||||
this.file = data;
|
||||
this.setState({
|
||||
loading: false
|
||||
});
|
||||
this.forceUpdate();
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
@ -153,17 +174,26 @@ export default class PdfViewer extends React.Component<
|
||||
}
|
||||
|
||||
render() {
|
||||
const {className, classnames: cx, width, height, background} = this.props;
|
||||
const {className, classnames: cx, height, background} = this.props;
|
||||
const {loading, inited} = this.state;
|
||||
const width = Math.max(this.props.width || this.state.width, 300);
|
||||
|
||||
return (
|
||||
<PdfView
|
||||
file={this.file}
|
||||
className={className}
|
||||
classnames={cx}
|
||||
width={width}
|
||||
height={height}
|
||||
background={background}
|
||||
/>
|
||||
<div ref={this.wrapper}>
|
||||
<Suspense fallback={<div>...</div>}>
|
||||
{inited ? (
|
||||
<PdfView
|
||||
file={this.file}
|
||||
loading={loading}
|
||||
className={className}
|
||||
classnames={cx}
|
||||
width={width}
|
||||
height={height}
|
||||
background={background}
|
||||
/>
|
||||
) : null}
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user