Skip to content

Commit

Permalink
Revert "Revert "feat: 支持PDF预览" (baidu#9694)"
Browse files Browse the repository at this point in the history
This reverts commit eccd5c7.
  • Loading branch information
yupeng12 committed Mar 1, 2024
1 parent a74dc8d commit 06aa45a
Show file tree
Hide file tree
Showing 15 changed files with 484 additions and 3 deletions.
54 changes: 54 additions & 0 deletions docs/zh-CN/components/pdf-viewer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
title: PDF Viewer
description:
type: 0
group: ⚙ 组件
menuName: PDFViewer 渲染
icon:
order: 24
---

## 基本用法

```schema: scope="body"
{
"type": "pdf-viewer",
"id": "pdf-viewer",
"src": "/examples/static/simple.pdf"
}
```

## 配合文件上传实现预览功能

配置和 `input-file` 相同的 `name` 即可

```schema: scope="body"
{
"type": "form",
"title": "",
"wrapWithPanel": false,
"body": [
{
"type": "input-file",
"name": "file",
"label": "File",
"asBlob": true,
"accept": ".pdf"
},
{
"type": "pdf-viewer",
"id": "pdf-viewer",
"name": "file"
}
]
}
```

## 属性表

| 属性名 | 类型 | 默认值 | 说明 |
| ---------- | ------ | ------ | ---------- |
| src | Api | | 文档地址 |
| width | number | 500 | 宽度 |
| height | number | - | 高度 |
| background | string | #fff | PDF 背景色 |
7 changes: 7 additions & 0 deletions examples/components/Components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,13 @@ export const components = [
import('../../docs/zh-CN/components/office-viewer.md').then(wrapDoc)
)
},
{
label: 'PDFViewer 渲染',
path: '/zh-CN/components/pdf-viewer',
component: React.lazy(() =>
import('../../docs/zh-CN/components/pdf-viewer.md').then(wrapDoc)
)
},
{
label: 'Progress 进度条',
path: '/zh-CN/components/progress',
Expand Down
8 changes: 8 additions & 0 deletions examples/components/Example.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ import Tab3Schema from './Tabs/Tab3';
import Loading from './Loading';
import CodeSchema from './Code';
import OfficeViewer from './OfficeViewer';
import PdfViewer from './PdfViewer';
import InputTableEvent from './EventAction/cmpt-event-action/InputTableEvent';
import WizardPage from './WizardPage';

Expand Down Expand Up @@ -912,6 +913,13 @@ export const examples = [
component: makeSchemaRenderer(OfficeViewer)
},

{
label: 'Pdf 预览',
icon: 'fa fa-file-pdf',
path: '/examples/pdf-viewer',
component: makeSchemaRenderer(PdfViewer)
},

{
label: '多 loading',
icon: 'fa fa-spinner',
Expand Down
23 changes: 23 additions & 0 deletions examples/components/PdfViewer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export default {
type: 'page',
body: {
type: 'form',
id: 'form',
debug: true,
wrapWithPanel: false,
body: [
{
type: 'input-file',
name: 'file',
label: '选择 PDF 文件预览效果(不会上传到服务器)',
asBlob: true,
accept: '.pdf'
},
{
type: 'pdf-viewer',
id: 'pdf-viewer',
name: 'file'
}
]
}
};
Binary file added examples/static/simple.pdf
Binary file not shown.
9 changes: 8 additions & 1 deletion fis-conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ fis.match('/examples/mod.js', {
isMod: false
});

fis.match('{markdown-it,moment-timezone}/**', {
fis.match('{markdown-it,moment-timezone,pdfjs-dist}/**', {
preprocessor: fis.plugin('js-require-file')
});

Expand Down Expand Up @@ -503,6 +503,7 @@ if (fis.project.currentMedia() === 'publish-sdk') {
'!amis-ui/lib/components/RichText.js',
'!amis-ui/lib/components/Tinymce.js',
'!amis-ui/lib/components/ColorPicker.js',
'!amis-ui/lib/components/PdfViewer.js',
'!react-color/**',
'!material-colors/**',
'!reactcss/**',
Expand Down Expand Up @@ -562,6 +563,11 @@ if (fis.project.currentMedia() === 'publish-sdk') {
'tinycolor2/**'
],

'pdf-viewer.js': [
'amis-ui/lib/components/PdfViewer.js',
'pdfjs-dist/build/pdf.worker.min.js'
],

'cropperjs.js': ['cropperjs/**', 'react-cropper/**'],

'barcode.js': ['src/components/BarCode.tsx', 'jsbarcode/**'],
Expand All @@ -584,6 +590,7 @@ if (fis.project.currentMedia() === 'publish-sdk') {
'!mpegts.js/**',
'!hls.js/**',
'!froala-editor/**',
'!pdfjs-dist/**',

'!amis-ui/lib/components/RichText.js',
'!zrender/**',
Expand Down
1 change: 1 addition & 0 deletions packages/amis-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"react-intersection-observer": "9.5.2",
"react-json-view": "1.21.3",
"react-overlays": "5.1.1",
"react-pdf": "^7.7.1",
"react-textarea-autosize": "8.3.3",
"react-transition-group": "4.4.2",
"react-visibility-sensor": "5.1.1",
Expand Down
3 changes: 2 additions & 1 deletion packages/amis-ui/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ const input = [
'./src/components/Markdown.tsx',
'./src/components/Tinymce.tsx',
'./src/components/RichText.tsx',
'./src/components/CityDB.ts'
'./src/components/CityDB.ts',
'./src/components/PdfViewer.tsx'
];

/** 获取子包编译后的入口路径,需要使用相对路径 */
Expand Down
45 changes: 45 additions & 0 deletions packages/amis-ui/scss/components/_pdf_viewer.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.#{$ns}PdfViewer {
position: relative;
height: 100%;
min-height: 500px;
display: flex;
justify-content: center;
padding: 50px 0;
&-Content {
width: max-content;
max-width: 100%;
&.is-loaded {
box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 4px 0px;
}
}

&-Loading {
text-align: center;
}

&-Tool {
position: absolute;
z-index: 10;
padding: 5px 15px;
bottom: 60px;
background-color: #444444;
border-radius: 10px;
color: #fff;
text-align: center;
user-select: none;
.gap {
margin: 0 4px;
}
.icon {
cursor: pointer;
width: 20px;
margin: 0 10px;
&:hover {
color: var(--colors-brand-5);
}
}
.page-input {
width: 40px;
}
}
}
1 change: 1 addition & 0 deletions packages/amis-ui/scss/themes/_common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -142,5 +142,6 @@
@import '../components/debug';
@import '../components/menu';
@import '../components/overflow-tpl';
@import '../components/pdf_viewer';

@import '../components/print';
143 changes: 143 additions & 0 deletions packages/amis-ui/src/components/PdfViewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/**
* @file PdfViewer.tsx PDF 预览
*
* @created: 2024/02/26
*/

import React from 'react';
import {themeable, ThemeProps} from 'amis-core';
import {Document, Page, pdfjs} from 'react-pdf';

import {Icon} from './icons';
import Input from './Input';
import Spinner from './Spinner';
// @ts-ignore
import pdfJSWorkerURL from 'pdfjs-dist/build/pdf.worker.min';
pdfjs.GlobalWorkerOptions.workerSrc = pdfJSWorkerURL;

export interface PdfViewerProps extends ThemeProps {
file?: ArrayBuffer;
width?: number;
height?: number;
background?: string;
}

const PdfViewer: React.FC<PdfViewerProps> = props => {
const {classnames: cx, className, width = 500} = 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 inputRef = React.useRef<HTMLInputElement>();

React.useEffect(() => {
if (props.file instanceof ArrayBuffer && props.file.byteLength > 0) {
setFile(props.file);
} else {
setFile(undefined);
}
}, [props.file]);

function handleLoadSuccess({numPages}: {numPages: number}) {
setLoaded(true);
setTotal(numPages);
}

function handleChangePage(idx: number) {
const newPage = page + idx;
if (newPage <= 0 || newPage > total) {
return;
}
setPage(newPage);
}

function handlePageBlur(event: React.ChangeEvent<HTMLInputElement>) {
const newPage = +event.target.value;
if (isNaN(newPage) || newPage <= 0 || newPage > total) {
if (inputRef.current) {
inputRef.current.value = page + '';
}
return;
}
setPage(newPage);
}

function handleChangeScale(t: number) {
setScale(scale * t);
}

if (!file) {
return null;
}

function renderLoading() {
return (
<div className={cx('PdfViewer-Loading')} style={{width: `${width}px`}}>
<Spinner />
</div>
);
}

function renderTool() {
return (
<div className={cx('PdfViewer-Tool')}>
<Icon
className="icon"
icon="prev"
onClick={() => handleChangePage(-1)}
/>
<Input
className="page-input"
value={page}
onBlur={handlePageBlur}
ref={inputRef}
/>
<span className="gap">/</span>
<span>{total}</span>
<Icon
className="icon"
icon="next"
onClick={() => handleChangePage(1)}
/>
<Icon
className="icon"
icon="zoom-in"
onClick={() => handleChangeScale(1.2)}
/>
<Icon
className="icon"
icon="zoom-out"
onClick={() => handleChangeScale(0.8)}
/>
</div>
);
}

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>
);
};

export default themeable(PdfViewer);
2 changes: 1 addition & 1 deletion packages/amis-ui/src/components/TimelineItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {localeable, LocaleProps} from 'amis-core';
import {themeable, ThemeProps} from 'amis-core';
import {Icon} from './icons';

import type {IconCheckedSchema} from 'amis-ui';
import type {IconCheckedSchema} from '../index';

export interface TimelineItemProps {
/**
Expand Down
1 change: 1 addition & 0 deletions packages/amis/src/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ export type SchemaType =
| 'input-formula'
| 'diff-editor'
| 'office-viewer'
| 'pdf-viewer'

// editor 系列
| 'editor'
Expand Down
1 change: 1 addition & 0 deletions packages/amis/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ import './renderers/Password';
import './renderers/DateRange';
import './renderers/MultilineText';
import './renderers/OfficeViewer';
import './renderers/PdfViewer';
import './renderers/AMIS';

import './compat';
Expand Down

0 comments on commit 06aa45a

Please sign in to comment.