@file-viewer/renderer-word 2.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +160 -0
- package/README.en.md +59 -0
- package/README.md +59 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +34 -0
- package/dist/openDocument.d.ts +2 -0
- package/dist/openDocument.js +122 -0
- package/dist/wordDoc.d.ts +5 -0
- package/dist/wordDoc.js +282 -0
- package/dist/wordDocx.d.ts +5 -0
- package/dist/wordDocx.js +983 -0
- package/package.json +74 -0
package/dist/wordDoc.js
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { defaultMsDocCss, parseMsDocToHtml } from 'msdoc-viewer';
|
|
2
|
+
import { applyPrintPageSize, buildPrintPageStyle, createFileViewerZoomChangeEmitter as createZoomChangeEmitter, formatCssPixels, registerFileViewerZoomProvider, unregisterFileViewerZoomProvider, } from '@file-viewer/core';
|
|
3
|
+
const PAGE_BREAK_MARKER = '<span class="msdoc-page-break"></span>';
|
|
4
|
+
const EMPTY_PAGE_HTML = '<p class="msdoc-paragraph"><br></p>';
|
|
5
|
+
const MSDOC_PAGE_SIZE = {
|
|
6
|
+
width: 794,
|
|
7
|
+
height: 1123
|
|
8
|
+
};
|
|
9
|
+
const MSDOC_MIN_SCALE = 0.24;
|
|
10
|
+
const MSDOC_MAX_SCALE = 3;
|
|
11
|
+
const MSDOC_ZOOM_STEP = 0.15;
|
|
12
|
+
const WORD_PAGE_CSS = `
|
|
13
|
+
.msdoc-stage{
|
|
14
|
+
box-sizing:border-box;
|
|
15
|
+
min-height:100%;
|
|
16
|
+
padding:32px 24px 48px;
|
|
17
|
+
background:#ececec;
|
|
18
|
+
display:flex;
|
|
19
|
+
flex-direction:column;
|
|
20
|
+
align-items:center;
|
|
21
|
+
gap:24px;
|
|
22
|
+
}
|
|
23
|
+
.msdoc-page{
|
|
24
|
+
width:min(100%,794px);
|
|
25
|
+
box-sizing:border-box;
|
|
26
|
+
}
|
|
27
|
+
.msdoc-page > .msdoc-root{
|
|
28
|
+
box-sizing:border-box;
|
|
29
|
+
width:100%;
|
|
30
|
+
max-width:none;
|
|
31
|
+
min-height:1123px;
|
|
32
|
+
padding:clamp(24px,7%,96px) clamp(20px,6%,88px);
|
|
33
|
+
background:#fff;
|
|
34
|
+
border:1px solid #d9d9d9;
|
|
35
|
+
box-shadow:0 1px 3px rgba(0,0,0,0.08), 0 12px 32px rgba(0,0,0,0.12);
|
|
36
|
+
overflow-wrap:anywhere;
|
|
37
|
+
}
|
|
38
|
+
/* 表格不能沿用正文的 anywhere 断词,否则旧 DOC 的列宽和单元格内容会被过度压缩。 */
|
|
39
|
+
.msdoc-page .msdoc-table{
|
|
40
|
+
display:table;
|
|
41
|
+
width:auto;
|
|
42
|
+
max-width:100%;
|
|
43
|
+
table-layout:auto!important;
|
|
44
|
+
border-collapse:collapse;
|
|
45
|
+
border-spacing:0;
|
|
46
|
+
}
|
|
47
|
+
.msdoc-page .msdoc-table tbody,
|
|
48
|
+
.msdoc-page .msdoc-table tr{
|
|
49
|
+
width:auto;
|
|
50
|
+
}
|
|
51
|
+
.msdoc-page .msdoc-cell{
|
|
52
|
+
min-width:1.5em;
|
|
53
|
+
padding:4px 6px;
|
|
54
|
+
vertical-align:top;
|
|
55
|
+
word-break:normal;
|
|
56
|
+
overflow-wrap:normal;
|
|
57
|
+
white-space:normal;
|
|
58
|
+
}
|
|
59
|
+
.msdoc-page .msdoc-cell .msdoc-paragraph{
|
|
60
|
+
margin:0 0 4px;
|
|
61
|
+
word-break:normal;
|
|
62
|
+
overflow-wrap:break-word;
|
|
63
|
+
}
|
|
64
|
+
.msdoc-page .msdoc-cell .msdoc-paragraph:last-child{
|
|
65
|
+
margin-bottom:0;
|
|
66
|
+
}
|
|
67
|
+
.msdoc-page .msdoc-cell span{
|
|
68
|
+
white-space:normal!important;
|
|
69
|
+
}
|
|
70
|
+
.msdoc-page .msdoc-page-break{
|
|
71
|
+
display:none;
|
|
72
|
+
}
|
|
73
|
+
@media (max-width: 860px){
|
|
74
|
+
.msdoc-stage{
|
|
75
|
+
padding:16px 12px 24px;
|
|
76
|
+
gap:16px;
|
|
77
|
+
}
|
|
78
|
+
.msdoc-page{
|
|
79
|
+
width:100%;
|
|
80
|
+
}
|
|
81
|
+
.msdoc-page > .msdoc-root{
|
|
82
|
+
min-height:auto;
|
|
83
|
+
padding:24px 20px;
|
|
84
|
+
box-shadow:none;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
`;
|
|
88
|
+
const MSDOC_ZOOM_CSS = `
|
|
89
|
+
.msdoc-zoom-viewer{
|
|
90
|
+
box-sizing:border-box;
|
|
91
|
+
height:100%;
|
|
92
|
+
overflow:auto;
|
|
93
|
+
background:#ececec;
|
|
94
|
+
}
|
|
95
|
+
.msdoc-zoom-viewer .msdoc-stage{
|
|
96
|
+
min-width:max-content;
|
|
97
|
+
}
|
|
98
|
+
.msdoc-zoom-viewer .msdoc-page{
|
|
99
|
+
position:relative;
|
|
100
|
+
max-width:none;
|
|
101
|
+
overflow:visible;
|
|
102
|
+
}
|
|
103
|
+
.msdoc-zoom-viewer .msdoc-page > .msdoc-root{
|
|
104
|
+
position:absolute;
|
|
105
|
+
top:0;
|
|
106
|
+
left:50%;
|
|
107
|
+
width:${MSDOC_PAGE_SIZE.width}px;
|
|
108
|
+
max-width:none;
|
|
109
|
+
margin:0;
|
|
110
|
+
transform-origin:top center;
|
|
111
|
+
}
|
|
112
|
+
`;
|
|
113
|
+
const getTargetWindow = (target) => {
|
|
114
|
+
return target.ownerDocument.defaultView;
|
|
115
|
+
};
|
|
116
|
+
function injectPageBreakMarkers(html) {
|
|
117
|
+
return html.replace(/<(p|table|section)([^>]*?)style="([^"]*?\bbreak-before\s*:\s*page;?[^"]*?)"([^>]*)>/gi, (match) => `${PAGE_BREAK_MARKER}${match}`);
|
|
118
|
+
}
|
|
119
|
+
function wrapAsWordPages(html) {
|
|
120
|
+
const normalizedHtml = injectPageBreakMarkers(html);
|
|
121
|
+
const pages = normalizedHtml.split(PAGE_BREAK_MARKER);
|
|
122
|
+
return `<div class="msdoc-stage">${pages.map(page => (`<section class="msdoc-page"><div class="msdoc-root">${page || EMPTY_PAGE_HTML}</div></section>`)).join('')}</div>`;
|
|
123
|
+
}
|
|
124
|
+
function prepareMsDocCloneForExport(target) {
|
|
125
|
+
const clone = target.cloneNode(true);
|
|
126
|
+
clone.classList.remove('msdoc-zoom-viewer');
|
|
127
|
+
clone.querySelectorAll('style[data-msdoc-zoom]').forEach(style => style.remove());
|
|
128
|
+
clone.querySelectorAll('.msdoc-stage, .msdoc-page, .msdoc-root').forEach(node => {
|
|
129
|
+
node.style.height = 'auto';
|
|
130
|
+
node.style.maxHeight = 'none';
|
|
131
|
+
node.style.overflow = 'visible';
|
|
132
|
+
node.style.transform = 'none';
|
|
133
|
+
});
|
|
134
|
+
clone.querySelectorAll('.msdoc-page').forEach(page => {
|
|
135
|
+
applyPrintPageSize(page, MSDOC_PAGE_SIZE, { heightMode: 'min' });
|
|
136
|
+
page.style.position = 'relative';
|
|
137
|
+
page.style.width = formatCssPixels(MSDOC_PAGE_SIZE.width);
|
|
138
|
+
page.style.maxWidth = 'none';
|
|
139
|
+
page.style.margin = '0 auto 18px';
|
|
140
|
+
const root = page.querySelector('.msdoc-root');
|
|
141
|
+
if (!root) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
root.style.position = 'relative';
|
|
145
|
+
root.style.top = 'auto';
|
|
146
|
+
root.style.left = 'auto';
|
|
147
|
+
root.style.width = formatCssPixels(MSDOC_PAGE_SIZE.width);
|
|
148
|
+
root.style.maxWidth = 'none';
|
|
149
|
+
root.style.minHeight = formatCssPixels(MSDOC_PAGE_SIZE.height);
|
|
150
|
+
root.style.height = 'auto';
|
|
151
|
+
root.style.transform = 'none';
|
|
152
|
+
root.style.transformOrigin = 'top left';
|
|
153
|
+
root.style.boxShadow = 'none';
|
|
154
|
+
root.style.border = '0';
|
|
155
|
+
root.style.overflow = 'visible';
|
|
156
|
+
});
|
|
157
|
+
return clone.innerHTML;
|
|
158
|
+
}
|
|
159
|
+
function buildMsDocPrintStyle() {
|
|
160
|
+
return buildPrintPageStyle({
|
|
161
|
+
selector: '.viewer-export-content .msdoc-page',
|
|
162
|
+
width: MSDOC_PAGE_SIZE.width,
|
|
163
|
+
height: MSDOC_PAGE_SIZE.height,
|
|
164
|
+
heightMode: 'min'
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
function makeMsDocResponsive(target) {
|
|
168
|
+
const pages = Array.from(target.querySelectorAll('.msdoc-page'));
|
|
169
|
+
if (!pages.length) {
|
|
170
|
+
return () => { };
|
|
171
|
+
}
|
|
172
|
+
target.classList.add('msdoc-zoom-viewer');
|
|
173
|
+
const view = getTargetWindow(target);
|
|
174
|
+
const ResizeObserverCtor = view === null || view === void 0 ? void 0 : view.ResizeObserver;
|
|
175
|
+
const style = target.ownerDocument.createElement('style');
|
|
176
|
+
style.dataset.msdocZoom = 'true';
|
|
177
|
+
style.textContent = MSDOC_ZOOM_CSS;
|
|
178
|
+
target.prepend(style);
|
|
179
|
+
const zoomEmitter = createZoomChangeEmitter();
|
|
180
|
+
let resizeFrame = 0;
|
|
181
|
+
let userZoom = 1;
|
|
182
|
+
let currentScale = 1;
|
|
183
|
+
let currentFitScale = 1;
|
|
184
|
+
const clampScale = (scale) => {
|
|
185
|
+
return Math.min(MSDOC_MAX_SCALE, Math.max(MSDOC_MIN_SCALE, Number(scale.toFixed(2))));
|
|
186
|
+
};
|
|
187
|
+
const resize = () => {
|
|
188
|
+
if (!view) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
view.cancelAnimationFrame(resizeFrame);
|
|
192
|
+
resizeFrame = view.requestAnimationFrame(() => {
|
|
193
|
+
let firstScale = 1;
|
|
194
|
+
let firstFitScale = 1;
|
|
195
|
+
pages.forEach(page => {
|
|
196
|
+
const root = page.querySelector('.msdoc-root');
|
|
197
|
+
if (!root) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const rootWidth = root.offsetWidth || MSDOC_PAGE_SIZE.width;
|
|
201
|
+
const rootHeight = Math.max(root.scrollHeight, root.offsetHeight, MSDOC_PAGE_SIZE.height);
|
|
202
|
+
const availableWidth = Math.max(target.clientWidth - 48, 120);
|
|
203
|
+
const fitScale = Math.min(1, Math.max(MSDOC_MIN_SCALE, availableWidth / rootWidth));
|
|
204
|
+
const scale = clampScale(fitScale * userZoom);
|
|
205
|
+
firstScale = scale;
|
|
206
|
+
firstFitScale = fitScale;
|
|
207
|
+
root.style.transform = `translateX(-50%) scale(${scale})`;
|
|
208
|
+
page.style.width = `${Math.ceil(Math.max(rootWidth * scale, 120))}px`;
|
|
209
|
+
page.style.height = `${Math.ceil(rootHeight * scale)}px`;
|
|
210
|
+
});
|
|
211
|
+
currentScale = firstScale;
|
|
212
|
+
currentFitScale = firstFitScale;
|
|
213
|
+
zoomEmitter.emit();
|
|
214
|
+
});
|
|
215
|
+
};
|
|
216
|
+
const getZoomState = () => ({
|
|
217
|
+
scale: currentScale,
|
|
218
|
+
label: `${Math.round(currentScale * 100)}%`,
|
|
219
|
+
canZoomIn: currentScale < MSDOC_MAX_SCALE,
|
|
220
|
+
canZoomOut: currentScale > MSDOC_MIN_SCALE,
|
|
221
|
+
canReset: userZoom !== 1,
|
|
222
|
+
minScale: MSDOC_MIN_SCALE,
|
|
223
|
+
maxScale: MSDOC_MAX_SCALE
|
|
224
|
+
});
|
|
225
|
+
const setUserZoom = (nextZoom) => {
|
|
226
|
+
userZoom = Math.min(6, Math.max(0.2, Number(nextZoom.toFixed(2))));
|
|
227
|
+
resize();
|
|
228
|
+
return getZoomState();
|
|
229
|
+
};
|
|
230
|
+
target.dataset.viewerZoomProvider = 'doc';
|
|
231
|
+
registerFileViewerZoomProvider(target, {
|
|
232
|
+
zoomIn: () => setUserZoom(userZoom + MSDOC_ZOOM_STEP),
|
|
233
|
+
zoomOut: () => setUserZoom(userZoom - MSDOC_ZOOM_STEP),
|
|
234
|
+
resetZoom: () => setUserZoom(1),
|
|
235
|
+
setZoom: scale => setUserZoom(scale / Math.max(currentFitScale, 0.01)),
|
|
236
|
+
getState: getZoomState,
|
|
237
|
+
subscribe: zoomEmitter.subscribe
|
|
238
|
+
});
|
|
239
|
+
const observer = ResizeObserverCtor ? new ResizeObserverCtor(resize) : null;
|
|
240
|
+
observer === null || observer === void 0 ? void 0 : observer.observe(target);
|
|
241
|
+
pages.forEach(page => {
|
|
242
|
+
const root = page.querySelector('.msdoc-root');
|
|
243
|
+
if (root) {
|
|
244
|
+
observer === null || observer === void 0 ? void 0 : observer.observe(root);
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
resize();
|
|
248
|
+
return () => {
|
|
249
|
+
view === null || view === void 0 ? void 0 : view.cancelAnimationFrame(resizeFrame);
|
|
250
|
+
observer === null || observer === void 0 ? void 0 : observer.disconnect();
|
|
251
|
+
unregisterFileViewerZoomProvider(target);
|
|
252
|
+
style.remove();
|
|
253
|
+
target.classList.remove('msdoc-zoom-viewer');
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* 渲染 doc 文件
|
|
258
|
+
*/
|
|
259
|
+
export default async function render(buffer, target, context) {
|
|
260
|
+
var _a;
|
|
261
|
+
const rendered = await parseMsDocToHtml(buffer, {
|
|
262
|
+
renderOptions: {
|
|
263
|
+
css: `${defaultMsDocCss()}\n${WORD_PAGE_CSS}`
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
target.innerHTML = `<style data-msdoc>${rendered.css}</style>${wrapAsWordPages(rendered.html)}`;
|
|
267
|
+
const disposeResponsive = makeMsDocResponsive(target);
|
|
268
|
+
(_a = context === null || context === void 0 ? void 0 : context.registerExportAdapter) === null || _a === void 0 ? void 0 : _a.call(context, {
|
|
269
|
+
includeDocumentStyles: false,
|
|
270
|
+
printStyle: buildMsDocPrintStyle,
|
|
271
|
+
toHtml: () => prepareMsDocCloneForExport(target)
|
|
272
|
+
});
|
|
273
|
+
return {
|
|
274
|
+
$el: target,
|
|
275
|
+
unmount() {
|
|
276
|
+
var _a;
|
|
277
|
+
(_a = context === null || context === void 0 ? void 0 : context.registerExportAdapter) === null || _a === void 0 ? void 0 : _a.call(context, null);
|
|
278
|
+
disposeResponsive();
|
|
279
|
+
target.innerHTML = '';
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
}
|