mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
feat(ooxml): 支持艺术字部分样式;修复外部数据变更不会重新渲染问题 (#6702)
This commit is contained in:
parent
7428ea8620
commit
1692273925
@ -87,12 +87,12 @@ Word 渲染支持以下功能:
|
||||
分页渲染的其它设置项
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| ------------------ | --------- | --------- | ------------------------------------------ | --- |
|
||||
| ------------------ | --------- | --------- | ------------------------------------------ |
|
||||
| page | `boolean` | false | 是否开启分页渲染 |
|
||||
| pageMarginBottom | `number` | 20 | 页面上下间距 |
|
||||
| pageBackground | `string` | '#FFF' | 页面内背景色 |
|
||||
| pageShadow | `boolean` | true | 是否显示阴影 |
|
||||
| pageWrap | `boolean` | true | 是否显示页面包裹 | |
|
||||
| pageWrap | `boolean` | true | 是否显示页面包裹 |
|
||||
| pageWrapBackground | `string` | '#ECECEC' | 页面包裹的背景色 |
|
||||
| zoom | `number` | | 缩放比例,取值 0-1 之间 |
|
||||
| zoomFitWidth | `boolean` | false | 自适应宽度缩放,如果设置了 zoom 将不会生效 |
|
||||
@ -194,54 +194,51 @@ Word 渲染支持以下功能:
|
||||
```schema
|
||||
{
|
||||
"type": "page",
|
||||
"data": {
|
||||
"users": [
|
||||
{
|
||||
name: 'u1',
|
||||
age: 10
|
||||
},
|
||||
{
|
||||
name: 'u2',
|
||||
age: 11
|
||||
}
|
||||
]
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "office-viewer",
|
||||
"src": "/examples/static/table-list.docx",
|
||||
"wordOptions": {
|
||||
"padding": "8px"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "action",
|
||||
"label": "下载文档",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "saveAs",
|
||||
"componentId": "office-viewer-table-list"
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"type": "office-viewer",
|
||||
"id": "office-viewer-table-list",
|
||||
"src": "/examples/static/table-list.docx",
|
||||
"wordOptions": {
|
||||
"padding": "8px"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "office-viewer",
|
||||
"id": "office-viewer-table-list",
|
||||
"src": "/examples/static/table-list.docx",
|
||||
"wordOptions": {
|
||||
"padding": "8px",
|
||||
"enableVar": true,
|
||||
"ignoreWidth": true
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
"type": "service",
|
||||
"api": "/api/mock2/sample/mirror?json=%7B%22users%22%3A%5B%7B%22name%22%3A%22u1%22%2C%22age%22%3A10%7D%2C%7B%22name%22%3A%22u2%22%2C%22age%22%3A11%7D%5D%7D",
|
||||
"body": [{
|
||||
"type": "office-viewer",
|
||||
"src": "/examples/static/table-list.docx",
|
||||
"wordOptions": {
|
||||
"padding": "8px",
|
||||
"enableVar": true,
|
||||
"ignoreWidth": true
|
||||
},
|
||||
"trackExpression": "${users}"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"type": "action",
|
||||
"label": "下载文档",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "saveAs",
|
||||
"componentId": "office-viewer-table-list"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
循环的语法是以 `{{#name}}` 开始,`{{/}}` 结束,在这期间的变量会取循环内的值
|
||||
循环的语法是以 `{{#name}}` 开始,`{{/}}` 结束,在这期间的变量会取循环内的值。
|
||||
|
||||
注意上面的例子用到了 `trackExpression`,默认情况下如果设置了 `enableVar`,每次上层数据变化都会重新渲染文档,如果文档较大可能会有性能问题,这时可以通过配置 `trackExpression` 来限制只有某个数据变化时才重新渲染。
|
||||
|
||||
## 不渲染模式
|
||||
|
||||
|
@ -263,12 +263,20 @@ function bulkUpdate2(req, res) {
|
||||
function mirror(req, res) {
|
||||
const json = JSON.parse(req.query.json);
|
||||
console.log('mirror', json);
|
||||
if ('status' in json) {
|
||||
return res.json(json);
|
||||
} else {
|
||||
return res.json({
|
||||
status: 0,
|
||||
data: json
|
||||
});
|
||||
|
||||
const response = () => {
|
||||
if ('status' in json) {
|
||||
return res.json(json);
|
||||
} else {
|
||||
return res.json({
|
||||
status: 0,
|
||||
data: json
|
||||
});
|
||||
}
|
||||
};
|
||||
if (req.query.waitSeconds) {
|
||||
return setTimeout(response, parseInt(req.query.waitSeconds, 10) * 1000);
|
||||
}
|
||||
|
||||
return response();
|
||||
}
|
||||
|
@ -85,7 +85,7 @@
|
||||
"rollup-pluginutils": "^2.8.2",
|
||||
"setprototypeof": "^1.2.0",
|
||||
"ts-jest": "^29.0.2",
|
||||
"vite": "^4.2.1",
|
||||
"vite": "^4.3.1",
|
||||
"vite-plugin-monaco-editor": "^1.1.0",
|
||||
"vite-plugin-svgr": "^2.2.2",
|
||||
"zrender": "^5.3.2"
|
||||
|
@ -7,6 +7,7 @@ import {BaseSchema} from '../Schema';
|
||||
import {
|
||||
ActionObject,
|
||||
createObject,
|
||||
filter,
|
||||
isApiOutdated,
|
||||
IScopedContext,
|
||||
Renderer,
|
||||
@ -28,7 +29,7 @@ export interface OfficeViewerSchema extends BaseSchema {
|
||||
/**
|
||||
* word 文档的渲染配置
|
||||
*/
|
||||
wordOptions?: {};
|
||||
wordOptions?: any;
|
||||
|
||||
/**
|
||||
* 是否显示文档
|
||||
@ -86,8 +87,18 @@ export default class OfficeViewer extends React.Component<
|
||||
this.renderWord();
|
||||
}
|
||||
|
||||
// 这个变量替换只会更新变化的部分,所以性能还能接受
|
||||
this.word?.updateVariable();
|
||||
if (props.wordOptions?.enableVar) {
|
||||
if (
|
||||
props.trackExpression &&
|
||||
filter(props.trackExpression, props.data) !==
|
||||
filter(prevProps.trackExpression, prevProps.data)
|
||||
) {
|
||||
this.renderWord();
|
||||
} else {
|
||||
// 目前 word 渲染比较快,所以全量渲染性能可以接受
|
||||
this.renderWord();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
File diff suppressed because it is too large
Load Diff
BIN
packages/ooxml-viewer/__tests__/docx/simple/loop-var-test.docx
Normal file
BIN
packages/ooxml-viewer/__tests__/docx/simple/loop-var-test.docx
Normal file
Binary file not shown.
BIN
packages/ooxml-viewer/__tests__/docx/simple/word-art.docx
Normal file
BIN
packages/ooxml-viewer/__tests__/docx/simple/word-art.docx
Normal file
Binary file not shown.
@ -61,7 +61,6 @@
|
||||
"ts-loader": "^9.2.3",
|
||||
"ts-node": "^10.4.0",
|
||||
"typescript": "^4.3.5",
|
||||
"vite": "^3.2.2",
|
||||
"xml-formatter": "^3.3.2"
|
||||
},
|
||||
"jest": {
|
||||
|
@ -66,10 +66,12 @@ export function parseChildColor(word: Word, element: Element): string {
|
||||
return srgbClr;
|
||||
|
||||
case 'a:schemeClr':
|
||||
const schemeClr = colorChild.getAttribute('val') || '';
|
||||
case 'w14:schemeClr':
|
||||
const schemeClr = getVal(colorChild);
|
||||
if (schemeClr) {
|
||||
return changeLum(colorChild, word.getThemeColor(schemeClr));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn(
|
||||
|
@ -342,7 +342,17 @@ export function parsePr(word: Word, element: Element, type: 'r' | 'p' = 'p') {
|
||||
break;
|
||||
|
||||
case 'w:rPr':
|
||||
// TODO: 这个有时候会不正确,需要再看看
|
||||
// TODO: 这个有时候和 r 里的 rPr 不一致,不知道如何处理
|
||||
const reflection = child.getElementsByTagName('w14:reflection').item(0);
|
||||
if (reflection) {
|
||||
// css 只支持在块级节点设置
|
||||
// 只支持一小部分设置项,另外因为只支持块级别的情况,所以看起来差异较大
|
||||
const reflectionDistance =
|
||||
parseSize(reflection, 'w4:dist', LengthUsage.Emu) || '0px';
|
||||
style[
|
||||
'-webkit-box-reflect'
|
||||
] = `below ${reflectionDistance} linear-gradient(transparent, white)`;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'w:rStyle':
|
||||
@ -429,26 +439,45 @@ export function parsePr(word: Word, element: Element, type: 'r' | 'p' = 'p') {
|
||||
|
||||
case 'w:outline':
|
||||
style['text-shadow'] =
|
||||
'-1pt -1pt 0 #AAA, 1pt -1pt 0 #AAA, -1pt 1pt 0 #AAA, 1pt 1pt 0 #AAA';
|
||||
'-1px -1px 0 #AAA, 1px -1px 0 #AAA, -1px 1px 0 #AAA, 1px 1px 0 #AAA';
|
||||
break;
|
||||
|
||||
case 'w:shadown':
|
||||
case 'w:imprint':
|
||||
if (getValBoolean(child, true)) {
|
||||
style['text-shadow'] = '1pt 1pt 2pt rgba(0, 0, 0, 0.6)';
|
||||
style['text-shadow'] = '1px 1px 2px rgba(0, 0, 0, 0.6)';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'w14:shadow':
|
||||
const blurRad =
|
||||
parseSize(child, 'w14:blurRad', LengthUsage.Emu) || '2pt';
|
||||
parseSize(child, 'w14:blurRad', LengthUsage.Emu) || '4px';
|
||||
// 其它结果算出来不像就先忽略了
|
||||
let color = 'rgba(0, 0, 0, 0.6)';
|
||||
const childColor = parseChildColor(word, child);
|
||||
if (childColor) {
|
||||
color = childColor;
|
||||
}
|
||||
style['text-shadow'] = `1pt 1pt ${blurRad} ${color}`;
|
||||
style['text-shadow'] = `1px 1px ${blurRad} ${color}`;
|
||||
break;
|
||||
|
||||
case 'w14:textOutline':
|
||||
const outlineWidth =
|
||||
parseSize(child, 'w14:w', LengthUsage.Emu) || '1px';
|
||||
|
||||
style['-webkit-text-stroke-width'] = outlineWidth;
|
||||
|
||||
let outlineColor = 'white';
|
||||
const fillColor = child.getElementsByTagName('w14:solidFill');
|
||||
if (fillColor.length > 0) {
|
||||
outlineColor = parseChildColor(word, fillColor.item(0)!) || 'white';
|
||||
}
|
||||
|
||||
style['-webkit-text-stroke-color'] = outlineColor;
|
||||
break;
|
||||
|
||||
case 'w14:reflection':
|
||||
// 在 rPr 里处理了
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -30,6 +30,11 @@ function generateDefaultStyle(word: Word) {
|
||||
|
||||
|
||||
/** docDefaults **/
|
||||
.${classPrefix} {
|
||||
--docx-theme-font-minorHAnsi: Calibri, Helvetica, Arial, 'Helvetica Neue';
|
||||
--docx-theme-font-minorEastAsia: 'PingFang SC', 'Microsoft YaHei', 'Hiragino Sans GB', 'STHeiti',
|
||||
'Microsoft YaHei';
|
||||
}
|
||||
|
||||
.${classPrefix} p {
|
||||
margin: 0;
|
||||
|
Loading…
Reference in New Issue
Block a user