即日起不再免费提供源码

This commit is contained in:
liyulin 2024-03-27 13:37:11 +08:00
parent eceb244bf1
commit dd2f71d6e4
743 changed files with 43605 additions and 60612 deletions

View File

@ -235,6 +235,8 @@ export default {
<img src="https://501351981.github.io/vue-office/examples/dist/static/wx.png" alt="赞助二维码" width="260"/>
## 打赏50及以上可向作者索要源码仅限自己项目使用不能复制开源
<span style="color: red;">打赏的朋友欢迎**添加微信**</span>,交流前端开发中遇到的技术、问题和困惑。
>【<span style="color:red;">**仅添加**打赏过的用户,不定期删除屏蔽朋友圈的好友</span>(为什么打赏了才能微信问问题?那别人为什么要先付出时间去解答你的问题?都是成年人了,人与人之间是价值交换,不是单向付出)】
@ -242,10 +244,3 @@ export default {
<img src="https://501351981.github.io/vue-office/examples/dist/static/wxqrcode.png" alt="个人微信" width="260"/>
### 恳请各位大佬不吝点赞,开源不易,感谢支持~~
## 我的其他库
- HowToCode前端编程之道探讨如何写出高质量的前端代码总结前端编程的各种方法论、原则、思维模型等。[《前端编程之道》](https://github.com/501351981/HowToCode)

View File

@ -1,3 +0,0 @@
node_modules/
lib/
dist/

View File

@ -1,24 +0,0 @@
module.exports = {
'env': {
'node': true,
'es2021': true
},
'extends': [
'eslint:recommended',
'plugin:vue/vue3-essential'
],
'overrides': [
],
'parserOptions': {
'ecmaVersion': 'latest',
'sourceType': 'module'
},
'plugins': [
'vue'
],
'rules': {
'semi': ['error','always'],
'no-multi-spaces': ['error', { ignoreEOLComments: false }],
'quotes': ['error', 'single']
}
};

3
core/.gitattributes vendored
View File

@ -1,3 +0,0 @@
*.js linguist-language=JavaScript
*.css linguist-language=JavaScript
*.html linguist-language=JavaScript

View File

@ -1 +0,0 @@
registry=https://registry.npmjs.org

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2023 hit757
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,15 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0,minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<title>@vue-office演示demo</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

View File

@ -1,6 +0,0 @@
51 error Error: Command failed with exit code 128: git tag v0.1.5 -m v0.1.5
51 error fatal: tag 'v0.1.5' already exists
51 error at makeError (/Users/liyulin/.nvm/versions/node/v16.15.0/lib/node_modules/lerna/node_modules/_execa@5.1.1@execa/lib/error.js:60:11)
51 error at handlePromise (/Users/liyulin/.nvm/versions/node/v16.15.0/lib/node_modules/lerna/node_modules/_execa@5.1.1@execa/index.js:118:26)
51 error at processTicksAndRejections (node:internal/process/task_queues:96:5)
51 error at async Promise.all (index 0)

View File

@ -1,5 +0,0 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"useWorkspaces": true,
"version": "0.2.2"
}

31249
core/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,79 +0,0 @@
{
"name": "vue-office",
"version": "1.0.0",
"description": "通过Vue开发的办公文档预览组件支持docx、pdf、ppt、excel(已实现)的预览",
"scripts": {
"dev": "node script/bak-vue.js && vite",
"build": "node script/bak-vue.js && vite build",
"lib": "node script/bak-vue.js bak && lerna run build",
"lib:js-excel": "node script/bak-vue.js bak && lerna run build --scope @js-preview/excel",
"lib:js-docx": "node script/bak-vue.js bak && lerna run build --scope @js-preview/docx",
"lib:vue-excel": "node script/bak-vue.js bak && lerna run build --scope @vue-office/excel",
"lib:vue-docx": "node script/bak-vue.js bak && lerna run build --scope @vue-office/docx",
"lib:js-pdf": "node script/bak-vue.js bak && lerna run build --scope @js-preview/pdf",
"lib:vue-pdf": "node script/bak-vue.js bak && lerna run build --scope @vue-office/pdf"
},
"dependencies": {
"@babel/plugin-transform-runtime": "^7.23.6",
"@babel/plugin-transform-template-literals": "^7.23.3",
"@babel/preset-env": "^7.22.5",
"@babel/runtime": "^7.23.6",
"@rollup/plugin-babel": "^6.0.3",
"@vue/compiler-sfc": "3.2.45",
"ant-design-vue": "^3.2.17",
"dayjs": "^1.11.7",
"docx-preview": "^0.1.20",
"exceljs": "^4.3.0",
"lodash": "^4.17.21",
"postcss": "^8.4.24",
"rimraf": "^4.1.2",
"rollup": "^3.26.0",
"rollup-plugin-postcss": "^4.0.2",
"tinycolor2": "^1.6.0",
"vue-demi": "^0.14.6",
"x-data-spreadsheet": "^1.1.9",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^25.0.2",
"@rollup/plugin-node-resolve": "^15.1.0",
"@rollup/plugin-terser": "^0.4.3",
"@vitejs/plugin-vue": "^4.0.0",
"@vue/composition-api": "^1.7.1",
"eslint": "^8.36.0",
"eslint-plugin-vue": "^9.9.0",
"lerna": "^6.4.1",
"less": "^4.1.3",
"less-loader": "^11.1.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-less": "^1.1.3",
"rollup-plugin-node-resolve": "^5.2.0",
"vite": "^4.0.0",
"vite-plugin-require-transform": "^1.0.9",
"vite-plugin-vue2": "^2.0.3",
"vue": "3.2.45",
"vue-router": "^4.1.6",
"vue-template-compiler": "2.6.14",
"vue2": "npm:vue@2.6.14",
"vue3": "npm:vue@3.2.45"
},
"workspaces": [
"packages/*"
],
"repository": {
"type": "git",
"url": "git@github.com:501351981/vue-office.git"
},
"keywords": [
"vue",
"docx",
"pdf",
"ppt",
"excel",
"docx-preview",
"excel-preview",
"pdf-preview"
],
"license": "MIT",
"author": "微信: _hit757_"
}

View File

@ -1,10 +0,0 @@
{
"presets": [
[
"@babel/preset-env",
{
"modules": false
}
]
]
}

View File

@ -1 +0,0 @@
registry=https://registry.npmjs.org

View File

@ -1 +0,0 @@
.vue-office-docx{height:100%;overflow-y:auto}.vue-office-docx .docx-wrapper>section.docx{margin-bottom:5px}@media screen and (max-width: 800px){.vue-office-docx .docx-wrapper{padding:10px}.vue-office-docx .docx-wrapper>section.docx{padding:10px!important;width:100%!important}}

View File

@ -1,31 +0,0 @@
export interface Options {
inWrapper?: boolean;
ignoreWidth?: boolean;
ignoreHeight?: boolean;
ignoreFonts?: boolean;
breakPages?: boolean;
debug?: boolean;
experimental?: boolean;
className?: string;
trimXmlDeclaration?: boolean;
renderHeaders?: boolean;
renderFooters?: boolean;
renderFootnotes?: boolean;
renderEndnotes?: boolean;
ignoreLastRenderedPageBreak?: boolean;
useBase64URL?: boolean;
useMathMLPolyfill?: boolean;
renderChanges?: boolean;
}
export interface JsDocxPreview {
preview: (src: string | ArrayBuffer | Blob) => Promise<any>;
save: (fileName?: string) => void;
setOptions: (options: Options) => void;
setRequestOptions: (requestOptions?: any) => void;
destroy: ()=> void;
}
declare const jsPreviewDocx: {
init: (container: HTMLElement, options?: Options, requestOptions?: any) => JsDocxPreview;
};
export default jsPreviewDocx;

View File

@ -1,5 +0,0 @@
import {init} from './src/main';
export default {
init
};

View File

@ -1,41 +0,0 @@
{
"name": "@js-preview/docx",
"type" :"module",
"version": "1.6.0",
"description": "",
"main": "lib/index.js",
"files": [
"lib/"
],
"scripts": {
"clean": "rimraf lib",
"copyReadme": "cp ../../../README.md README.md",
"copyType": "cp index.d.ts lib/index.d.ts",
"copyCss": "cp ./index.css ./lib/index.css",
"copy": "npm run copyCss && npm run copyType && npm run copyReadme",
"build": "npm run clean && rollup --config rollup.config.js && npm run copy"
},
"repository": {
"type": "git",
"url": "git@github.com:501351981/vue-office.git"
},
"keywords": [
"vue",
"docx",
"pdf",
"ppt",
"excel",
"docx-preview",
"excel-preview",
"pdf-preview"
],
"license": "MIT",
"author": "微信: _hit757_",
"gitHead": "d20568113bec480f6ca72924f6d0c1e3b0f1fe15",
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"dependencies": {
}
}

View File

@ -1,26 +0,0 @@
import {getBabelOutputPlugin} from '@rollup/plugin-babel';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import terser from '@rollup/plugin-terser';
export default {
input: 'index.js',
output:[
{
file: 'lib/index.js',
name: 'jsPreviewDocx',
format: 'es',
plugins: [getBabelOutputPlugin({ presets: ['@babel/preset-env'] })]
},
{
file: 'lib/index.umd.js',
name: 'jsPreviewDocx',
format: 'umd'
}
],
plugins: [
nodeResolve(),
commonjs(),
terser()
]
};

View File

@ -1,7 +0,0 @@
if(typeof window.setImmediate === 'undefined' ){
window.setImmediate = function (func, ...args){
setTimeout(()=>func(args));
};
}
export default {}

View File

@ -1,63 +0,0 @@
import hack from './hack.js';
import docx from '../../vue-docx/src/docx';
import {download as downloadFile} from '../../../utils/url.js';
class JsDocxPreview {
container = null;
wrapper = null;
wrapperMain = null;
options = {};
requestOptions = {};
fileData = null;
constructor(container, options={}, requestOptions={}) {
this.container = container;
this.options = options;
this.requestOptions = requestOptions;
this.createWrapper();
}
createWrapper(){
this.wrapper = document.createElement('div');
this.wrapper.className = 'vue-office-docx';
this.wrapperMain = document.createElement('div');
this.wrapperMain.className = 'vue-office-docx-main';
this.wrapper.appendChild(this.wrapperMain);
this.container.appendChild(this.wrapper);
}
setOptions(options) {
this.options = options;
}
setRequestOptions(requestOptions) {
this.requestOptions = requestOptions;
}
preview(src){
return new Promise((resolve, reject) => {
docx.getData(src, this.requestOptions).then(async res =>{
this.fileData = await docx.getBlob(res);
docx.render(this.fileData, this.wrapperMain, this.options).then(() => {
resolve();
}).catch(e => {
docx.render('', this.wrapperMain, this.options);
reject(e);
});
}).catch(err=>{
docx.render('', this.wrapperMain, this.options);
reject(err);
});
});
}
save(fileName){
downloadFile(fileName || `js-preview-docx-${new Date().getTime()}.docx`,this.fileData);
}
destroy(){
this.container.removeChild(this.wrapper);
this.container = null;
this.wrapper = null;
this.wrapperMain = null;
this.options = null;
this.requestOptions = null;
}
}
export function init(container, options, requestOptions){
return new JsDocxPreview(container, options, requestOptions);
}

View File

@ -1 +0,0 @@
registry=https://registry.npmjs.org

View File

@ -1,762 +0,0 @@
.x-spreadsheet {
font-size: 13px;
line-height: normal;
user-select: none;
-moz-user-select: none;
font-family: 'Lato', 'Source Sans Pro', Roboto, Helvetica, Arial, sans-serif;
box-sizing: content-box;
background: #fff;
-webkit-font-smoothing: antialiased;
}
.x-spreadsheet textarea {
font: 400 13px Arial, 'Lato', 'Source Sans Pro', Roboto, Helvetica, sans-serif;
}
.x-spreadsheet-sheet {
position: relative;
overflow: hidden;
}
.x-spreadsheet-table {
vertical-align: bottom;
}
.x-spreadsheet-tooltip {
font-family: inherit;
position: absolute;
padding: 5px 10px;
color: #fff;
border-radius: 1px;
background: #000000;
font-size: 12px;
z-index: 201;
}
.x-spreadsheet-tooltip:before {
pointer-events: none;
position: absolute;
left: calc(50% - 4px);
top: -4px;
content: "";
width: 8px;
height: 8px;
background: inherit;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
z-index: 1;
box-shadow: 1px 1px 3px -1px rgba(0, 0, 0, 0.3);
}
.x-spreadsheet-color-palette {
padding: 5px;
}
.x-spreadsheet-color-palette table {
margin: 0;
padding: 0;
border-collapse: separate;
border-spacing: 2;
background: #fff;
}
.x-spreadsheet-color-palette table td {
margin: 0;
cursor: pointer;
border: 1px solid transparent;
}
.x-spreadsheet-color-palette table td:hover {
border-color: #ddd;
}
.x-spreadsheet-color-palette table td .x-spreadsheet-color-palette-cell {
width: 16px;
height: 16px;
}
.x-spreadsheet-border-palette {
padding: 6px;
}
.x-spreadsheet-border-palette table {
margin: 0;
padding: 0;
border-collapse: separate;
border-spacing: 0;
background: #fff;
table-layout: fixed;
}
.x-spreadsheet-border-palette table td {
margin: 0;
}
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-left {
border-right: 1px solid #eee;
padding-right: 6px;
}
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell {
width: 30px;
height: 30px;
cursor: pointer;
text-align: center;
}
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell:hover {
background-color: #eee;
}
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-right {
padding-left: 6px;
}
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-right .x-spreadsheet-line-type {
position: relative;
left: 0;
top: -3px;
}
.x-spreadsheet-dropdown {
position: relative;
}
.x-spreadsheet-dropdown .x-spreadsheet-dropdown-content {
position: absolute;
z-index: 200;
background: #fff;
box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15);
}
.x-spreadsheet-dropdown.bottom-left .x-spreadsheet-dropdown-content {
top: calc(100% + 5px);
left: 0;
}
.x-spreadsheet-dropdown.bottom-right .x-spreadsheet-dropdown-content {
top: calc(100% + 5px);
right: 0;
}
.x-spreadsheet-dropdown.top-left .x-spreadsheet-dropdown-content {
bottom: calc(100% + 5px);
left: 0;
}
.x-spreadsheet-dropdown.top-right .x-spreadsheet-dropdown-content {
bottom: calc(100% + 5px);
right: 0;
}
.x-spreadsheet-dropdown .x-spreadsheet-dropdown-title {
padding: 0 5px;
display: inline-block;
}
/* resizer **/
.x-spreadsheet-resizer {
position: absolute;
z-index: 11;
}
.x-spreadsheet-resizer .x-spreadsheet-resizer-hover {
background-color: rgba(75, 137, 255, 0.25);
}
.x-spreadsheet-resizer .x-spreadsheet-resizer-line {
position: absolute;
}
.x-spreadsheet-resizer.horizontal {
cursor: row-resize;
}
.x-spreadsheet-resizer.horizontal .x-spreadsheet-resizer-line {
border-bottom: 2px dashed #4b89ff;
left: 0;
bottom: 0;
}
.x-spreadsheet-resizer.vertical {
cursor: col-resize;
}
.x-spreadsheet-resizer.vertical .x-spreadsheet-resizer-line {
border-right: 2px dashed #4b89ff;
top: 0;
right: 0;
}
/* scrollbar */
.x-spreadsheet-scrollbar {
position: absolute;
bottom: 0;
right: 0;
background-color: #f4f5f8;
opacity: 0.9;
z-index: 12;
}
.x-spreadsheet-scrollbar.horizontal {
right: 15px;
overflow-x: scroll;
overflow-y: hidden;
}
.x-spreadsheet-scrollbar.horizontal > div {
height: 1px;
background: #ddd;
}
.x-spreadsheet-scrollbar.vertical {
bottom: 15px;
overflow-x: hidden;
overflow-y: scroll;
}
.x-spreadsheet-scrollbar.vertical > div {
width: 1px;
background: #ddd;
}
/* @{css-prefix}-overlayer */
.x-spreadsheet-overlayer {
position: absolute;
left: 0;
top: 0;
z-index: 10;
}
.x-spreadsheet-overlayer .x-spreadsheet-overlayer-content {
position: absolute;
overflow: hidden;
pointer-events: none;
width: 100%;
height: 100%;
}
.x-spreadsheet-editor,
.x-spreadsheet-selector {
box-sizing: content-box;
position: absolute;
overflow: hidden;
pointer-events: none;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* @{css-prefix}-selector */
.x-spreadsheet-selector .hide-input {
position: absolute;
z-index: 0;
}
.x-spreadsheet-selector .hide-input input {
padding: 0;
width: 0;
border: none!important;
}
.x-spreadsheet-selector .x-spreadsheet-selector-area {
position: absolute;
border: 2px solid #4b89ff;
background: rgba(75, 137, 255, 0.1);
z-index: 5;
}
.x-spreadsheet-selector .x-spreadsheet-selector-clipboard,
.x-spreadsheet-selector .x-spreadsheet-selector-autofill {
position: absolute;
background: transparent;
z-index: 100;
}
.x-spreadsheet-selector .x-spreadsheet-selector-clipboard {
border: 2px dashed #4b89ff;
}
.x-spreadsheet-selector .x-spreadsheet-selector-autofill {
border: 1px dashed rgba(0, 0, 0, 0.45);
}
.x-spreadsheet-selector .x-spreadsheet-selector-corner {
pointer-events: auto;
position: absolute;
cursor: crosshair;
font-size: 0;
height: 5px;
width: 5px;
right: -5px;
bottom: -5px;
border: 2px solid #ffffff;
background: #4b89ff;
}
.x-spreadsheet-editor {
z-index: 20;
}
.x-spreadsheet-editor .x-spreadsheet-editor-area {
position: absolute;
text-align: left;
border: 2px solid #4b89ff;
line-height: 0;
z-index: 100;
pointer-events: auto;
}
.x-spreadsheet-editor .x-spreadsheet-editor-area textarea {
box-sizing: content-box;
border: none;
padding: 0 3px;
outline: none;
resize: none;
text-align: start;
overflow-y: hidden;
font: 400 13px Arial, 'Lato', 'Source Sans Pro', Roboto, Helvetica, sans-serif;
color: inherit;
white-space: normal;
word-wrap: break-word;
line-height: 22px;
margin: 0;
}
.x-spreadsheet-editor .x-spreadsheet-editor-area .textline {
overflow: hidden;
visibility: hidden;
position: fixed;
top: 0;
left: 0;
}
.x-spreadsheet-item {
user-select: none;
background: 0;
border: 1px solid transparent;
outline: none;
height: 26px;
color: rgba(0, 0, 0, 0.9);
line-height: 26px;
list-style: none;
padding: 2px 10px;
cursor: default;
text-align: left;
overflow: hidden;
}
.x-spreadsheet-item.disabled {
pointer-events: none;
opacity: 0.5;
}
.x-spreadsheet-item:hover,
.x-spreadsheet-item.active {
background: rgba(0, 0, 0, 0.05);
}
.x-spreadsheet-item.divider {
height: 0;
padding: 0;
margin: 5px 0;
border: none;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
.x-spreadsheet-item .label {
float: right;
opacity: 0.65;
font-size: 1em;
}
.x-spreadsheet-item.state,
.x-spreadsheet-header.state {
padding-left: 35px!important;
position: relative;
}
.x-spreadsheet-item.state:before,
.x-spreadsheet-header.state:before {
content: '';
position: absolute;
width: 10px;
height: 10px;
left: 12px;
top: calc(50% - 5px);
background: rgba(0, 0, 0, 0.08);
border-radius: 2px;
}
.x-spreadsheet-item.state.checked:before,
.x-spreadsheet-header.state.checked:before {
background: #4b89ff;
}
.x-spreadsheet-checkbox {
position: relative;
display: inline-block;
backface-visibility: hidden;
outline: 0;
vertical-align: baseline;
font-style: normal;
font-size: 1rem;
line-height: 1em;
}
.x-spreadsheet-checkbox > input {
position: absolute;
top: 0;
left: 0;
opacity: 0!important;
outline: 0;
z-index: -1;
}
.x-spreadsheet-suggest,
.x-spreadsheet-contextmenu,
.x-spreadsheet-sort-filter {
position: absolute;
box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15);
background: #fff;
z-index: 100;
width: 260px;
pointer-events: auto;
overflow: auto;
}
.x-spreadsheet-suggest {
width: 200px;
}
.x-spreadsheet-filter {
border: 1px solid #e9e9e9;
font-size: 12px;
margin: 10px;
}
.x-spreadsheet-filter .x-spreadsheet-header {
padding: 0.5em 0.75em;
background: #f8f8f9;
border-bottom: 1px solid #e9e9e9;
border-left: 1px solid transparent;
}
.x-spreadsheet-filter .x-spreadsheet-body {
height: 200px;
overflow-y: auto;
}
.x-spreadsheet-filter .x-spreadsheet-body .x-spreadsheet-item {
height: 20px;
line-height: 20px;
}
.x-spreadsheet-sort-filter .x-spreadsheet-buttons {
margin: 10px;
}
.x-spreadsheet-bottombar {
height: 40px;
padding: 0 30px;
text-align: left;
background: #f5f6f7;
display: flex;
}
.x-spreadsheet-bottombar {
position: relative;
border-top: 1px solid #e0e2e4;
}
.x-spreadsheet-bottombar .x-spreadsheet-menu > li {
line-height: 40px;
height: 40px;
padding-top: 0;
padding-bottom: 0;
vertical-align: middle;
border-right: 1px solid #e8eaed;
}
.x-spreadsheet-menu {
list-style: none;
margin: 0;
padding: 0;
user-select: none;
}
.x-spreadsheet-menu > li {
float: left;
line-height: 1.25em;
padding: 0.785em 1em;
margin: 0;
vertical-align: middle;
text-align: left;
font-weight: 400;
color: #80868b;
white-space: nowrap;
cursor: pointer;
transition: all 0.3s;
font-weight: bold;
}
.x-spreadsheet-menu > li.active {
background-color: #fff;
color: rgba(0, 0, 0, 0.65);
}
.x-spreadsheet-menu > li .x-spreadsheet-dropdown {
display: inline-block;
}
.x-spreadsheet-print {
position: absolute;
left: 0;
top: 0;
z-index: 100;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.x-spreadsheet-print-bar {
background: #424242;
height: 60px;
line-height: 60px;
padding: 0 30px;
}
.x-spreadsheet-print-bar .-title {
color: #fff;
font-weight: bold;
font-size: 1.2em;
float: left;
}
.x-spreadsheet-print-bar .-right {
float: right;
margin-top: 12px;
}
.x-spreadsheet-print-content {
display: flex;
flex: auto;
flex-direction: row;
background: #d0d0d0;
height: calc(100% - 60px);
}
.x-spreadsheet-print-content .-sider {
flex: 0 0 300px;
width: 300px;
border-left: 2px solid #ccc;
background: #fff;
}
.x-spreadsheet-print-content .-content {
flex: auto;
overflow-x: auto;
overflow-y: scroll;
height: 100%;
}
.x-spreadsheet-canvas-card-wraper {
margin: 40px 20px;
}
.x-spreadsheet-canvas-card {
background: #fff;
margin: auto;
page-break-before: auto;
page-break-after: always;
box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 3px rgba(0, 0, 0, 0.12), 0 4px 5px 0 rgba(0, 0, 0, 0.2);
}
.x-spreadsheet-calendar {
color: rgba(0, 0, 0, 0.65);
background: #ffffff;
user-select: none;
}
.x-spreadsheet-calendar .calendar-header {
font-weight: 700;
line-height: 30px;
text-align: center;
width: 100%;
float: left;
background: #f9fafb;
}
.x-spreadsheet-calendar .calendar-header .calendar-header-left {
padding-left: 5px;
float: left;
}
.x-spreadsheet-calendar .calendar-header .calendar-header-right {
float: right;
}
.x-spreadsheet-calendar .calendar-header .calendar-header-right a {
padding: 3px 0;
margin-right: 2px;
border-radius: 2px;
}
.x-spreadsheet-calendar .calendar-header .calendar-header-right a:hover {
background: rgba(0, 0, 0, 0.08);
}
.x-spreadsheet-calendar .calendar-body {
border-collapse: collapse;
border-spacing: 0;
}
.x-spreadsheet-calendar .calendar-body th,
.x-spreadsheet-calendar .calendar-body td {
width: 14.28571429%;
min-width: 32px;
text-align: center;
font-weight: 700;
line-height: 30px;
padding: 0;
}
.x-spreadsheet-calendar .calendar-body td > .cell:hover {
background: #ecf6fd;
}
.x-spreadsheet-calendar .calendar-body td > .cell.active,
.x-spreadsheet-calendar .calendar-body td > .cell.active:hover {
background: #ecf6fd;
color: #2185D0;
}
.x-spreadsheet-calendar .calendar-body td > .cell.disabled {
pointer-events: none;
opacity: 0.5;
}
.x-spreadsheet-datepicker {
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2);
position: absolute;
left: 0;
top: calc(100% + 5px);
z-index: 10;
width: auto;
}
.x-spreadsheet-buttons {
display: flex;
justify-content: flex-end;
}
.x-spreadsheet-buttons .x-spreadsheet-button {
margin-left: 8px;
}
.x-spreadsheet-button {
display: inline-block;
border-radius: 3px;
line-height: 1em;
min-height: 1em;
white-space: nowrap;
text-align: center;
cursor: pointer;
font-size: 1em;
font-weight: 700;
padding: 0.75em 1em;
color: rgba(0, 0, 0, 0.6);
background: #E0E1E2;
text-decoration: none;
font-family: "Lato", "proxima-nova", "Helvetica Neue", Arial, sans-serif;
outline: none;
vertical-align: baseline;
zoom: 1;
user-select: none;
transition: all 0.1s linear;
}
.x-spreadsheet-button.active,
.x-spreadsheet-button:hover {
background-color: #C0C1C2;
color: rgba(0, 0, 0, 0.8);
}
.x-spreadsheet-button.primary {
color: #fff;
background-color: #2185D0;
}
.x-spreadsheet-button.primary:hover,
.x-spreadsheet-button.primary.active {
color: #fff;
background-color: #1678c2;
}
.x-spreadsheet-form-input {
font-size: 1em;
position: relative;
font-weight: 400;
display: inline-flex;
color: rgba(0, 0, 0, 0.87);
}
.x-spreadsheet-form-input input {
z-index: 1;
margin: 0;
max-width: 100%;
flex: 1 0 auto;
outline: 0;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
text-align: left;
line-height: 30px;
height: 30px;
padding: 0 8px;
background: #fff;
border: 1px solid #e9e9e9;
border-radius: 3px;
transition: box-shadow 0.1s ease, border-color 0.1s ease;
box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06);
}
.x-spreadsheet-form-input input:focus {
border-color: #4b89ff;
box-shadow: inset 0 1px 2px rgba(75, 137, 255, 0.2);
}
.x-spreadsheet-form-select {
position: relative;
display: inline-block;
background: #fff;
border: 1px solid #e9e9e9;
border-radius: 2px;
cursor: pointer;
color: rgba(0, 0, 0, 0.87);
user-select: none;
box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06);
}
.x-spreadsheet-form-select .input-text {
text-overflow: ellipsis;
white-space: nowrap;
min-width: 60px;
width: auto;
height: 30px;
line-height: 30px;
padding: 0 8px;
}
.x-spreadsheet-form-fields {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.x-spreadsheet-form-fields .x-spreadsheet-form-field {
flex: 0 1 auto;
}
.x-spreadsheet-form-fields .x-spreadsheet-form-field .label {
display: inline-block;
margin: 0 10px 0 0;
}
.x-spreadsheet-form-field {
display: block;
vertical-align: middle;
margin-left: 10px;
margin-bottom: 10px;
}
.x-spreadsheet-form-field:first-child {
margin-left: 0;
}
.x-spreadsheet-form-field.error .x-spreadsheet-form-select,
.x-spreadsheet-form-field.error input {
border-color: #f04134;
}
.x-spreadsheet-form-field .tip {
color: #f04134;
font-size: 0.9em;
}
.x-spreadsheet-dimmer {
display: none;
position: absolute;
top: 0 !important;
left: 0 !important;
width: 100%;
height: 100%;
text-align: center;
vertical-align: middle;
background-color: rgba(0, 0, 0, 0.6);
opacity: 0;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-duration: 0.5s;
animation-duration: 0.5s;
transition: background-color 0.5s linear;
user-select: none;
z-index: 1000;
}
.x-spreadsheet-dimmer.active {
display: block;
opacity: 1;
}
form fieldset {
border: none;
}
form fieldset label {
display: block;
margin-bottom: 0.5em;
font-size: 1em;
color: #666;
}
form fieldset select {
font-size: 1.1em;
width: 100%;
background-color: #fff;
border: none;
border-bottom: 2px solid #ddd;
padding: 0.5em 0.85em;
border-radius: 2px;
}
.x-spreadsheet-modal,
.x-spreadsheet-toast {
font-size: 13px;
position: fixed;
z-index: 1001;
text-align: left;
line-height: 1.25em;
min-width: 360px;
color: rgba(0, 0, 0, 0.87);
font-family: 'Lato', 'Source Sans Pro', Roboto, Helvetica, Arial, sans-serif;
border-radius: 4px;
border: 1px solid rgba(0, 0, 0, 0.1);
background-color: #fff;
background-clip: padding-box;
box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 8px;
}
.x-spreadsheet-toast {
background-color: rgba(255, 255, 255, 0.85);
}
.x-spreadsheet-modal-header,
.x-spreadsheet-toast-header {
font-weight: 600;
background-clip: padding-box;
background-color: rgba(255, 255, 255, 0.85);
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 4px 4px 0 0;
}
.x-spreadsheet-toast-header {
color: #F2711C;
}
.x-spreadsheet-modal-header {
border-bottom: 1px solid #e0e2e4;
background: rgba(0, 0, 0, 0.08);
font-size: 1.0785em;
}
.x-spreadsheet-modal-header,
.x-spreadsheet-modal-content,
.x-spreadsheet-toast-header,
.x-spreadsheet-toast-content {
padding: 0.75em 1em;
}
.x-spreadsheet-menu li:first-child {
display: none;
}
.vue-office-excel {
height: 100%;
}

View File

@ -1,17 +0,0 @@
export interface Options {
minColLength?: number;
minRowLength?: number;
showContextmenu?: boolean;
}
export interface JsExcelPreview {
preview: (src: string | ArrayBuffer | Blob) => Promise<any>;
save: (fileName?: string) => void;
setOptions: (options: Options) => void;
setRequestOptions: (requestOptions?: any) => void;
destroy: ()=> void;
}
declare const jsPreviewExcel: {
init: (container: HTMLElement, options?: Options, requestOptions?: any) => JsExcelPreview;
};
export default jsPreviewExcel;

View File

@ -1,5 +0,0 @@
import {init} from './src/main';
export default {
init
};

View File

@ -1,41 +0,0 @@
{
"name": "@js-preview/excel",
"type" :"module",
"version": "1.7.3",
"description": "",
"main": "lib/index.js",
"files": [
"lib/"
],
"scripts": {
"clean": "rimraf lib",
"copyReadme": "cp ../../../README.md README.md",
"copyType": "cp index.d.ts lib/index.d.ts",
"copyCss": "cp ./index.css ./lib/index.css",
"copy": "npm run copyCss && npm run copyType && npm run copyReadme",
"build": "npm run clean && rollup --config rollup.config.js && npm run copy"
},
"repository": {
"type": "git",
"url": "git@github.com:501351981/vue-office.git"
},
"keywords": [
"vue",
"docx",
"pdf",
"ppt",
"excel",
"docx-preview",
"excel-preview",
"pdf-preview"
],
"license": "MIT",
"author": "微信: _hit757_",
"gitHead": "d20568113bec480f6ca72924f6d0c1e3b0f1fe15",
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"dependencies": {
}
}

View File

@ -1,28 +0,0 @@
import { getBabelOutputPlugin } from '@rollup/plugin-babel';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import postcss from 'rollup-plugin-postcss';
import terser from '@rollup/plugin-terser';
export default {
input: 'index.js',
output:[
{
file: 'lib/index.js',
name: 'jsPreviewExcel',
format: 'es',
plugins: [getBabelOutputPlugin({ presets: ['@babel/preset-env'] })]
},
{
file: 'lib/index.umd.js',
name: 'jsPreviewExcel',
format: 'umd'
}
],
plugins: [
nodeResolve(),
commonjs(),
postcss(),
terser()
]
};

View File

@ -1,180 +0,0 @@
import Spreadsheet from 'x-data-spreadsheet';
import {getData, readExcelData, transferExcelToSpreadSheet} from '../../vue-excel/src/excel';
import {renderImage, clearCache} from '../../vue-excel/src/media';
import {readOnlyInput} from '../../vue-excel/src/hack';
import {debounce} from 'lodash';
import {download as downloadFile} from '../../../utils/url.js';
const defaultOptions = {
xls: false,
minColLength: 20
};
class JsExcelPreview {
container = null;
wrapper = null;
wrapperMain = null;
options = {};
requestOptions = {};
mediasSource = [];
workbookDataSource = {
_worksheets:[]
};
sheetIndex = 1;
ctx = null;
xs = null;
offset = null;
observer = null;
fileData = null;
constructor(container, options={}, requestOptions={}) {
this.container = container;
this.options = {...defaultOptions, ...options};
this.requestOptions = requestOptions;
this.createWrapper();
this.initSpreadsheet();
this.hack();
}
createWrapper(){
this.wrapper = document.createElement('div');
this.wrapper.className = 'vue-office-excel';
this.wrapperMain = document.createElement('div');
this.wrapperMain.className = 'vue-office-excel-main';
this.wrapper.appendChild(this.wrapperMain);
this.container.appendChild(this.wrapper);
}
initSpreadsheet(){
this.xs = new Spreadsheet(this.wrapperMain, {
mode: 'read',
showToolbar: false,
showContextmenu: this.options.showContextmenu || false,
view: {
height: () => this.wrapper && this.wrapper.clientHeight || 300,
width: () => this.wrapper && this.wrapper.clientWidth || 1200,
},
row: {
height: 24,
len: 100
},
col: {
len: 26,
width: 80,
indexWidth: 60,
minWidth: 60,
},
autoFocus: false
}).loadData({});
let that = this;
let swapFunc = this.xs.bottombar.swapFunc;
this.xs.bottombar.swapFunc = function (index) {
swapFunc.call(that.xs.bottombar, index);
that.sheetIndex = index;
setTimeout(()=>{
that.xs.reRender();
renderImage(that.ctx, that.mediasSource,that.workbookDataSource._worksheets[that.sheetIndex], that.offset);
});
};
let clear = this.xs.sheet.editor.clear;
this.xs.sheet.editor.clear = function (...args){
clear.apply(that.xs.sheet.editor, args);
setTimeout(()=>{
renderImage(that.ctx, that.mediasSource,that.workbookDataSource._worksheets[that.sheetIndex], that.offset);
});
};
let setOffset = this.xs.sheet.editor.setOffset;
this.xs.sheet.editor.setOffset = function (...args){
setOffset.apply(that.xs.sheet.editor, args);
that.offset = args[0];
renderImage(that.ctx, that.mediasSource,that.workbookDataSource._worksheets[that.sheetIndex], that.offset);
};
const canvas = this.wrapperMain.querySelector('canvas');
this.ctx = canvas.getContext('2d');
}
renderExcel(buffer){
this.fileData = buffer;
return readExcelData(buffer, this.options.xls).then(workbook => {
if (!workbook._worksheets || workbook._worksheets.length === 0) {
throw new Error('未获取到数据,可能文件格式不正确或文件已损坏');
}
if(this.options.beforeTransformData && typeof this.options.beforeTransformData === 'function' ){
workbook = this.options.beforeTransformData(workbook);
}
let {workbookData, medias, workbookSource} = transferExcelToSpreadSheet(workbook, this.options);
if(this.options.transformData && typeof this.options.transformData === 'function' ){
workbookData = this.options.transformData(workbookData);
}
this.mediasSource = medias;
this.workbookDataSource = workbookSource;
this.offset = null;
this.sheetIndex = 0;
clearCache();
this.xs.loadData(workbookData);
renderImage(this.ctx, this.mediasSource,this.workbookDataSource._worksheets[this.sheetIndex], this.offset);
}).catch(e => {
this.mediasSource = [];
this.workbookDataSource = {
_worksheets:[]
};
clearCache();
this.xs.loadData({});
return Promise.reject(e);
});
}
hack(){
const observerCallback = debounce(readOnlyInput, 200).bind(this, this.wrapperMain);
this.observer = new MutationObserver(observerCallback);
const observerConfig = { attributes: true, childList: true, subtree: true };
this.observer.observe(this.wrapperMain, observerConfig);
observerCallback(this.wrapperMain);
}
setOptions(options) {
this.options = options;
}
setRequestOptions(requestOptions) {
this.requestOptions = requestOptions;
}
preview(src){
return new Promise(((resolve, reject) => {
getData(src, this.requestOptions).then((res)=>{
this.renderExcel(res).then(resolve).catch(e =>{
this.mediasSource = [];
this.workbookDataSource = {
_worksheets:[]
};
this.xs.loadData({});
reject(e);
});
}).catch(e => {
this.mediasSource = [];
this.workbookDataSource = {
_worksheets:[]
};
this.xs.loadData({});
reject(e);
});
}));
}
save(fileName){
downloadFile(fileName || `js-preview-excel-${new Date().getTime()}.xlsx`,this.fileData);
}
destroy(){
this.observer.disconnect();
this.container.removeChild(this.wrapper);
this.container = null;
this.wrapper = null;
this.wrapperMain = null;
this.ctx = null;
this.xs = null;
this.observer = null;
this.options = null;
this.requestOptions = null;
this.mediasSource = null;
this.workbookDataSource = null;
}
}
export function init(container, options, requestOptions){
return new JsExcelPreview(container, options, requestOptions);
}

View File

@ -1,19 +0,0 @@
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1",
"ios": "8"
},
"useBuiltIns": "usage",
"corejs": "3.32.0"
}
]
]
}

View File

@ -1 +0,0 @@
registry=https://registry.npmjs.org

View File

@ -1,27 +0,0 @@
export interface Options {
staticFileUrl?: string;
width?: number;
data?: BinaryData;
httpHeaders?: Object;
withCredentials?: boolean;
password?: string;
length?: number;
docBaseUrl?: string;
cMapUrl?: string;
cMapPacked?: boolean;
CMapReaderFactory?: Object;
useSystemFonts?: boolean;
}
export interface JsPdfPreview {
preview: (src: string | ArrayBuffer | Blob) => Promise<any>;
rerender: () => Promise<any>;
save: (fileName?: string) => void;
setOptions: (options: Options) => void;
setRequestOptions: (requestOptions?: any) => void;
destroy: ()=> void;
}
declare const jsPreviewPdf: {
init: (container: HTMLElement, options?: Options, requestOptions?: any) => JsPdfPreview;
};
export default jsPreviewPdf;

View File

@ -1,5 +0,0 @@
import {init} from './src/main';
export default {
init
};

View File

@ -1,40 +0,0 @@
{
"name": "@js-preview/pdf",
"type" :"module",
"version": "1.6.5",
"description": "",
"main": "lib/index.js",
"files": [
"lib/"
],
"scripts": {
"clean": "rimraf lib",
"copyReadme": "cp ../../../README.md README.md",
"copyType": "cp index.d.ts lib/index.d.ts",
"copy": "npm run copyType && npm run copyReadme",
"build": "npm run clean && rollup --config rollup.config.js && npm run copy"
},
"repository": {
"type": "git",
"url": "git@github.com:501351981/vue-office.git"
},
"keywords": [
"vue",
"docx",
"pdf",
"ppt",
"excel",
"docx-preview",
"excel-preview",
"pdf-preview"
],
"license": "MIT",
"author": "微信: _hit757_",
"gitHead": "d20568113bec480f6ca72924f6d0c1e3b0f1fe15",
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"dependencies": {
}
}

View File

@ -1,26 +0,0 @@
import {getBabelOutputPlugin} from '@rollup/plugin-babel';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import terser from '@rollup/plugin-terser';
export default {
input: 'index.js',
output:[
{
file: 'lib/index.js',
name: 'jsPreviewPdf',
format: 'es',
plugins: [getBabelOutputPlugin({ presets: ['@babel/preset-env'] })]
},
{
file: 'lib/index.umd.js',
name: 'jsPreviewPdf',
format: 'umd'
}
],
plugins: [
nodeResolve(),
commonjs(),
terser()
]
};

View File

@ -1,215 +0,0 @@
import {workerStr} from './worker.js';
import {pdfLibJsStr} from './pdf.js';
import {download as downloadFile, getUrl, loadScript} from '../../../utils/url';
import omit from 'lodash/omit';
const pdfJsLibSrc = `data:text/javascript;base64,${pdfLibJsStr}`;
const PdfJsWorkerSrc = `data:text/javascript;base64,${workerStr}`;
let pdfJsLibLoaded = false;
let workerLoaded = false;
class JsPdfPreview{
container = null;
wrapper = null;
wrapperMain = null;
options = {};
requestOptions = {};
pdfDocument = null;
loopCheckTimer = null;
constructor(container, options={}, requestOptions={}) {
this.container = container;
this.options = {
staticFileUrl: 'https://unpkg.com/pdfjs-dist@3.1.81/',
...options
};
this.requestOptions = requestOptions;
this.createWrapper();
}
createWrapper(){
this.wrapper = document.createElement('div');
this.wrapper.className = 'vue-office-pdf';
this.wrapper.setAttribute('style', 'text-align: center;overflow-y: auto;');
this.container.appendChild(this.wrapper);
}
createWrapperMain(){
this.wrapperMain = document.createElement('div');
this.wrapperMain.className = 'vue-office-pdf-wrapper';
this.wrapperMain.setAttribute('style', 'background: gray; padding: 30px 0;position: relative;');
this.wrapper.appendChild(this.wrapperMain);
}
createCanvas(num){
let existCanvas = this.wrapperMain.querySelectorAll('canvas');
if(existCanvas[num -1]){
return [existCanvas[num -1], existCanvas[num -1].getContext('2d')];
}
const canvas = document.createElement('canvas');
canvas.setAttribute('style', 'width:100%');
this.wrapperMain.appendChild(canvas);
return [canvas, canvas.getContext('2d')];
}
installPdfScript() {
return loadScript(pdfJsLibSrc).then(() => {
if (window.pdfjsLib && !workerLoaded) {
workerLoaded = true;
window.pdfjsLib.GlobalWorkerOptions.workerSrc = PdfJsWorkerSrc;
} else {
return Promise.reject('window.pdfjsLib未找到');
}
});
}
waitPdfjsLoad(){
return new Promise((resolve)=>{
const loopCheck = () =>{
if(window.pdfjsLib) {
resolve();
}else{
this.loopCheckTimer = setTimeout(loopCheck, 10);
}
};
loopCheck();
});
}
checkPdfLib() {
if (window.pdfjsLib) {
return Promise.resolve();
}
if(!pdfJsLibLoaded){
pdfJsLibLoaded = true;
return this.installPdfScript();
}else{
return this.waitPdfjsLoad();
}
}
getDocument(src){
const loadingTask = window.pdfjsLib.getDocument({
url: getUrl(src),
httpHeaders: this.requestOptions && this.requestOptions.headers,
withCredentials: this.requestOptions && this.requestOptions.withCredentials,
cMapUrl: `${this.options.staticFileUrl.endsWith('/') ? this.options.staticFileUrl : this.options.staticFileUrl + '/'}cmaps/`,
cMapPacked: true,
enableXfa: true,
...omit(this.options, ['width', 'staticFileUrl'])
});
return loadingTask.promise;
}
renderSinglePage(num){
return this.pdfDocument.getPage(num).then((pdfPage) => {
const viewport = pdfPage.getViewport({scale: 2});
const outputScale = window.devicePixelRatio > 2 ? 1.5 : 2;
let [canvas, ctx] = this.createCanvas(num);
canvas.width = Math.floor(viewport.width * outputScale);
canvas.height = Math.floor(viewport.height * outputScale);
let domWidth = Math.floor(viewport.width);
let domHeight = Math.floor(viewport.height);
if (this.options.width) {
let scale = this.options.width / domWidth;
domWidth = Math.floor(this.options.width);
domHeight = Math.floor(domHeight * scale);
}
let wrapperWidth = this.wrapperMain.getBoundingClientRect().width - 20;
if(domWidth > wrapperWidth){
let scale = wrapperWidth / domWidth;
domWidth = Math.floor(wrapperWidth);
domHeight = Math.floor(domHeight * scale);
}
canvas.style.width = domWidth + 'px';
canvas.style.height = domHeight + 'px';
const transform = outputScale !== 1
? [outputScale, 0, 0, outputScale, 0, 0]
: null;
const renderTask = pdfPage.render({
canvasContext: ctx,
transform,
viewport
});
return renderTask.promise.then(() => {
if (this.pdfDocument.numPages > num) {
return this.renderSinglePage(num + 1);
}
});
});
}
renderPage(){
if(!this.wrapperMain){
this.createWrapperMain();
}else{
let canvas = this.wrapperMain.querySelectorAll('canvas');
if(canvas.length > this.pdfDocument.numPages){
for(let i = canvas.length-1; i >= this.pdfDocument.numPages; i--){
this.wrapperMain.removeChild(canvas[i]);
}
}
}
return this.renderSinglePage(1);
}
clearAllCanvas(){
if(this.wrapperMain){
this.wrapper.removeChild(this.wrapperMain);
this.wrapperMain = null;
}
}
setOptions(options) {
this.options = options;
}
setRequestOptions(requestOptions) {
this.requestOptions = requestOptions;
}
preview(src){
return new Promise(((resolve, reject) => {
if(!src){
this.clearAllCanvas();
reject(new Error('预览地址不能为空'));
return;
}
this.checkPdfLib().then(_=>{
this.getDocument(src).then(pdf=>{
this.pdfDocument && this.pdfDocument.destroy();
this.pdfDocument = pdf;
this.renderPage().then(_=>{
resolve();
}).catch(e=>{
this.clearAllCanvas();
reject(e);
});
}).catch(e=>{
this.clearAllCanvas();
reject(e);
});
}).catch(e=>{
this.clearAllCanvas();
reject(e);
});
}));
}
rerender(){
return this.renderPage().then(_=>{
return Promise.resolve();
}).catch(e=>{
this.clearAllCanvas();
return Promise.reject(e);
});
}
save(fileName){
this.pdfDocument && this.pdfDocument._transport && this.pdfDocument._transport.getData().then(fileData=>{
downloadFile(fileName || `js-preview-pdf-${new Date().getTime()}.pdf`,fileData.buffer);
});
}
destroy(){
this.container.removeChild(this.wrapper);
this.container = null;
this.wrapper = null;
this.wrapperMain = null;
this.options = {};
this.requestOptions = {};
this.pdfDocument && this.pdfDocument.destroy();
this.pdfDocument = null;
this.loopCheckTimer && clearTimeout(this.loopCheckTimer);
}
}
export function init(container, options, requestOptions){
return new JsPdfPreview(container, options, requestOptions);
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
registry=https://registry.npmjs.org

View File

@ -1,7 +0,0 @@
declare const VueOfficeDocx: {
install?: (vue: any) => void;
src: string|ArrayBuffer|Blob;
requestOptions?: any;
options?: any
};
export default VueOfficeDocx;

View File

@ -1,8 +0,0 @@
import hack from './src/hack';
import VueOfficeDocx from './src/main.vue';
VueOfficeDocx.install = function (Vue) {
Vue.component(VueOfficeDocx.name, VueOfficeDocx);
};
export default VueOfficeDocx;

View File

@ -1,48 +0,0 @@
{
"name": "@vue-office/docx",
"version": "1.6.0",
"description": "",
"main": "lib/index.js",
"files": [
"lib/"
],
"scripts": {
"clean": "rimraf lib",
"copyFile2": "cp lib/v2/vue-office-docx.umd.js lib/v2/index.js && cp lib/v2/style.css lib/v2/index.css",
"copyFile3": "cp lib/v3/vue-office-docx.umd.js lib/v3/index.js && cp lib/v3/style.css lib/v3/index.css",
"copyReadme": "cp ../../../README.md README.md",
"copyType": "cp index.d.ts lib/index.d.ts",
"copyScripts": "mkdir lib/script/ && cp ../../script/postinstall.js lib/script/postinstall.js && cp ../../script/switch-cli.js lib/script/switch-cli.js && cp ../../script/utils.js lib/script/utils.js",
"build:2": "npx vue-demi-switch 2 vue2 && vite build && npm run copyFile2",
"build:3": "npx vue-demi-switch 3 vue3 && vite build && npm run copyFile3",
"build": "npm run clean && npm run build:2 && npm run build:3 && npm run copyScripts && npm run copyReadme && npm run copyType",
"postinstall": "node lib/script/postinstall.js"
},
"peerDependencies": {
"@vue/composition-api": "^1.7.1",
"vue": "^2.0.0 || >=3.0.0",
"vue-demi": "^0.14.6"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
},
"repository": {
"type": "git",
"url": "git@github.com:501351981/vue-office.git"
},
"keywords": [
"vue",
"docx",
"pdf",
"ppt",
"excel",
"docx-preview",
"excel-preview",
"pdf-preview"
],
"license": "MIT",
"author": "微信: _hit757_",
"gitHead": "d20568113bec480f6ca72924f6d0c1e3b0f1fe15"
}

View File

@ -1,56 +0,0 @@
/*eslint-disable*/
import {renderAsync} from 'docx-preview';
const defaultOptions = {
ignoreLastRenderedPageBreak: false
};
function getData(src, options = {}) {
if (typeof src === 'string') {
return fetchDocx(src, options);
}
return Promise.resolve(src);
}
function fetchDocx(src, options) {
return fetch(src, options).then(res => {
if (res.status !== 200) {
return Promise.reject(res);
}
return res;
});
}
async function getBlob(data){
let blob;
if (data instanceof Blob) {
blob = data;
} else if (data instanceof Response) {
blob = await data.blob();
} else if (data instanceof ArrayBuffer) {
blob = new Blob([data]);
}
return blob
}
function render(data, container, options = {}) {
if (!data) {
container.innerHTML = '';
return Promise.resolve();
}
let blob;
if (data instanceof Blob) {
blob = data;
} else if (data instanceof Response) {
blob = data.blob();
} else if (data instanceof ArrayBuffer) {
blob = new Blob([data]);
}
return renderAsync(blob, container, container, {...defaultOptions, ...options});
}
export default {
getData,
render,
getBlob
};

View File

@ -1,8 +0,0 @@
//乾坤下不能渲染问题兼容
if(typeof window.setImmediate === 'undefined' ){
window.setImmediate = function (func, ...args){
setTimeout(()=>func(args));
};
}
export default {}

View File

@ -1,95 +0,0 @@
<script>
import {defineComponent, ref, onMounted, watch} from 'vue-demi';
import docx from './docx';
import {download as downloadFile} from '../../../utils/url';
export default defineComponent({
name: 'VueOfficeDocx',
props: {
src: [String, ArrayBuffer, Blob],
requestOptions: {
type: Object,
default: () => ({})
},
options:{
type: Object,
default: () => ({})
}
},
emits: ['rendered', 'error'],
setup(props, {emit}) {
const rootRef = ref(null);
let fileData = null;
function init() {
let container = rootRef.value;
docx.getData(props.src, props.requestOptions).then(async res => {
fileData = await docx.getBlob(res);
docx.render(fileData, container, props.options).then(() => {
emit('rendered');
}).catch(e => {
docx.render('', container, props.options);
emit('error', e);
});
}).catch(e => {
docx.render('', container, props.options);
emit('error', e);
});
}
onMounted(() => {
if (props.src) {
init();
}
});
watch(() => props.src, () => {
if (props.src) {
init();
} else {
docx.render('', rootRef.value, props.options).then(() => {
emit('rendered');
});
}
});
function save(fileName){
downloadFile(fileName || `vue-office-docx-${new Date().getTime()}.docx`,fileData);
}
return {
rootRef,
save
};
}
});
</script>
<template>
<div class="vue-office-docx">
<div class="vue-office-docx-main" ref="rootRef"></div>
</div>
</template>
<style lang="less">
.vue-office-docx {
height: 100%;
overflow-y: auto;
.docx-wrapper {
> section.docx {
margin-bottom: 5px;
}
}
}
@media screen and (max-width: 800px) {
.vue-office-docx {
.docx-wrapper {
padding: 10px;
> section.docx {
padding: 10px !important;
width: 100% !important;
}
}
}
}
</style>

View File

@ -1,37 +0,0 @@
import { defineConfig } from 'vite';
import { createVuePlugin } from 'vite-plugin-vue2';
import vue3 from '@vitejs/plugin-vue';
import * as compiler from '@vue/compiler-sfc';
import { isVue2 } from 'vue-demi';
const { resolve } = require('path');
export default defineConfig({
plugins: [
isVue2
? createVuePlugin()
: vue3({
compiler: compiler
}),
],
build: {
target: 'es2015',
outDir: 'lib/v' + (isVue2 ? '2' : '3'),
lib: {
entry: resolve(__dirname, 'index.js'), //指定组件编译入口文件
name: 'vue-office-docx',
fileName: 'vue-office-docx',
},
optimizeDeps: {
exclude: ['vue-demi']
},
rollupOptions: {
external: ['vue-demi','vue'],
output: {
globals: {
vue: 'Vue',
'vue-demi': 'VueDemi'
},
},
},
},
});

View File

@ -1 +0,0 @@
registry=https://registry.npmjs.org

View File

@ -1,12 +0,0 @@
export interface Options {
minColLength?: number;
minRowLength?: number;
showContextmenu?: boolean;
}
declare const VueOfficeExcel: {
install?: (vue: any) => void;
src: string|ArrayBuffer|Blob;
requestOptions?: any;
options?: Options;
};
export default VueOfficeExcel;

View File

@ -1,7 +0,0 @@
import VueOfficeExcel from './src/main.vue';
VueOfficeExcel.install = function (Vue) {
Vue.component(VueOfficeExcel.name, VueOfficeExcel);
};
export default VueOfficeExcel;

View File

@ -1,48 +0,0 @@
{
"name": "@vue-office/excel",
"version": "1.7.3",
"description": "",
"main": "lib/index.js",
"files": [
"lib/"
],
"scripts": {
"clean": "rimraf lib",
"copyFile2": "cp lib/v2/vue-office-excel.umd.js lib/v2/index.js && cp src/index.css lib/v2/index.css",
"copyFile3": "cp lib/v3/vue-office-excel.umd.js lib/v3/index.js && cp src/index.css lib/v3/index.css",
"copyReadme": "cp ../../../README.md README.md",
"copyType": "cp index.d.ts lib/index.d.ts",
"copyScripts": "mkdir lib/script/ && cp ../../script/postinstall.js lib/script/postinstall.js && cp ../../script/switch-cli.js lib/script/switch-cli.js && cp ../../script/utils.js lib/script/utils.js",
"build:2": "npx vue-demi-switch 2 vue2 && vite build && npm run copyFile2",
"build:3": "npx vue-demi-switch 3 vue3 && vite build && npm run copyFile3",
"build": "npm run clean && npm run build:2 && npm run build:3 && npm run copyScripts && npm run copyReadme && npm run copyType",
"postinstall": "node lib/script/postinstall.js"
},
"peerDependencies": {
"@vue/composition-api": "^1.7.1",
"vue": "^2.0.0 || >=3.0.0",
"vue-demi": "^0.14.6"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
},
"repository": {
"type": "git",
"url": "git@github.com:501351981/vue-office.git"
},
"keywords": [
"vue",
"docx",
"pdf",
"ppt",
"excel",
"docx-preview",
"excel-preview",
"pdf-preview"
],
"license": "MIT",
"author": "微信: _hit757_",
"gitHead": "d20568113bec480f6ca72924f6d0c1e3b0f1fe15"
}

View File

@ -1,24 +0,0 @@
function HexToRgb (str) {
str = str.replace('#', '');
var hxs = str.match(/../g);
for (var i = 0; i < 3; i++) hxs[i] = parseInt(hxs[i], 16);
return hxs;
}
function RgbToHex (a, b, c) {
var hexs = [a.toString(16), b.toString(16), c.toString(16)];
for (var i = 0; i < 3; i++) if (hexs[i].length == 1) hexs[i] = '0' + hexs[i];
return '#' + hexs.join('');
}
export function getDarkColor(color, level) {
var rgbc = HexToRgb(color);
for (var i = 0; i < 3; i++) rgbc[i] = Math.floor(rgbc[i] * (1 - level));
return RgbToHex(rgbc[0], rgbc[1], rgbc[2]);
}
export function getLightColor(color, level) {
var rgbc = HexToRgb(color);
for (var i = 0; i < 3; i++) rgbc[i] = Math.floor((255 - rgbc[i]) * level + rgbc[i]);
return RgbToHex(rgbc[0], rgbc[1], rgbc[2]);
}

View File

@ -1,430 +0,0 @@
import * as Excel from 'exceljs/dist/exceljs';
import {getUrl} from '../../../utils/url';
import tinycolor from 'tinycolor2';
import {cloneDeep, get, find} from 'lodash';
import {getDarkColor, getLightColor} from './color';
import dayjs from 'dayjs';
import {read, write} from 'xlsx';
const themeColor = [
'#FFFFFF',
'#000000',
'#BFBFBF',
'#323232',
'#4472C4',
'#ED7D31',
'#A5A5A5',
'#FFC000',
'#5B9BD5',
'#71AD47'
];
const indexedColor = [
'#000000',
'#FFFFFF',
'#FF0000',
'#00FF00',
'#0000FF',
'#FFFF00',
'#FF00FF',
'#00FFFF',
'#000000',
'#FFFFFF',
'#FF0000',
'#00FF00',
'#0000FF',
'#FFFF00',
'#FF00FF',
'#00FFFF',
'#800000',
'#008000',
'#000080',
'#808000',
'#800080',
'#008080',
'#C0C0C0',
'#808080',
'#9999FF',
'#993366',
'#FFFFCC',
'#CCFFFF',
'#660066',
'#FF8080',
'#0066CC',
'#CCCCFF',
'#000080',
'#FF00FF',
'#FFFF00',
'#00FFFF',
'#800080',
'#800000',
'#008080',
'#0000FF',
'#00CCFF',
'#CCFFFF',
'#CCFFCC',
'#FFFF99',
'#99CCFF',
'#FF99CC',
'#CC99FF',
'#FFCC99',
'#3366FF',
'#33CCCC',
'#99CC00',
'#FFCC00',
'#FF9900',
'#FF6600',
'#666699',
'#969696',
'#003366',
'#339966',
'#003300',
'#333300',
'#993300',
'#993366',
'#333399',
'#333333',
'#FFFFFF'
];
let defaultColWidth = 80;
let defaultRowHeight = 24;
export function getData(src, options={}) {
return requestExcel(getUrl(src), options);
}
function requestExcel(src, options) {
return new Promise(function(resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.open(options.method || 'GET', src, true);
xhr.responseType = options.responseType || 'arraybuffer';
xhr.onload = function() {
if (xhr.status === 200) {
resolve(xhr.response);
} else {
reject(xhr.status);
}
};
xhr.onerror = function() {
reject(xhr.status);
};
xhr.withCredentials = options.withCredentials || false;
if(options.headers) {
Object.keys(options.headers).forEach(function(key) {
xhr.setRequestHeader(key, options.headers[key]);
});
}
xhr.send(options.body);
});
}
export function readExcelData(buffer, xls){
try {
if(xls){
const workbook = read(buffer, {type: 'array'});
buffer = write(workbook, { bookType: 'xlsx', type: 'array' });
}
const wb = new Excel.Workbook();
return wb.xlsx.load(buffer);
}catch (e){
console.warn(e);
return Promise.reject(e);
}
}
function transferColumns(excelSheet, spreadSheet, options){
for(let i = 0;i < (excelSheet.columns || []).length; i++){
spreadSheet.cols[i.toString()] = {};
if(excelSheet.columns[i].width) {
spreadSheet.cols[i.toString()].width = excelSheet.columns[i].width * 6 + (options.widthOffset || 0);
} else {
spreadSheet.cols[i.toString()].width = defaultColWidth + (options.widthOffset || 0);
}
}
spreadSheet.cols.len = Math.max(Object.keys(spreadSheet.cols).length, options.minColLength || 0);
}
function getCellText(cell){
//console.log(cell);
let {numFmt, value, type} = cell;
switch (type){
case 2: //数字
try {
//numFmt:
// "0.00%"
// "0.00_);(0.00)"
// "#,##0.000_);(#,##0.000)" 千分位
// "#,##0.000;[Red]#,##0.000"
if(cell.style.numFmt){
if(cell.style.numFmt.endsWith('%')){
let precision = cell.style.numFmt.match(/\.(\d+)%/);
if(precision){
return (value * 100).toFixed(precision[1].length) + '%';
}else {
return value * 100 + '%';
}
}else if(/0(\.0+)?/.test(cell.style.numFmt)){
let prefix = '';
if(cell.style.numFmt.startsWith('$')){
prefix = '$';
}else if(cell.style.numFmt.startsWith('"¥')){
prefix = '¥';
}
if(value === 0 && cell.style.numFmt.startsWith('_')){
return '-';
}
let precision = cell.style.numFmt.match(/0\.(0+)(_|;|$)/);
if(precision){
precision = precision[1].length;
}else{
precision = 0;
}
let result = value.toFixed(precision) + '';
if(cell.style.numFmt.includes('#,##')){
//千分位
result = result.split('.');
let number = result[0].split('').reverse();
let newNumber = [];
for(let i = 0; i< number.length; i++){
newNumber.push(number[i]);
if((i+1) % 3 === 0 && i < number.length - 1 && number[i+1] !== '-'){
newNumber.push(',');
}
}
result[0] = newNumber.reverse().join('');
result = result.join('.');
}
return prefix + result;
}
}
return value + '';
}catch (e){
return value;
}
case 3: //字符串
return value;
case 4: //日期
switch (numFmt){
case 'yyyy-mm-dd;@':
return dayjs(value).format('YYYY-MM-DD');
case 'mm-dd-yy':
return dayjs(value).format('YYYY/MM/DD');
case '[$-F800]dddd, mmmm dd, yyyy':
return dayjs(value).format('YYYY年M月D日 ddd');
case 'm"月"d"日";@':
return dayjs(value).format('M月D日');
case 'yyyy/m/d h:mm;@':
case 'm/d/yy "h":mm':
return dayjs(value).subtract(8, 'hour').format('YYYY/M/DD HH:mm');
case 'h:mm;@':
return dayjs(value).format('HH:mm');
default:
return dayjs(value).format('YYYY-MM-DD');
}
case 5: //超链接
return value.text;
case 6: //公式
return get(value, 'result.error') || value.result;
case 8: //富文本
return cell.text;
case 9: //Boolean
return cell.text.toUpperCase();
default:
return value;
}
}
function transferArgbColor(originColor){
if(typeof originColor === 'object'){
return '#000000';
}
if(/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.test(originColor)){
return originColor.startsWith('#') ? originColor : '#' + originColor;
}
originColor = originColor.trim().toLowerCase(); //去掉前后空格
let color = {};
try {
let argb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(originColor);
color.r = parseInt(argb[2], 16);
color.g = parseInt(argb[3], 16);
color.b = parseInt(argb[4], 16);
color.a = parseInt(argb[1], 16) / 255;
return tinycolor(`rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`).toHexString();
} catch (e) {
console.warn(e);
}
}
function transferThemeColor(themeIndex, tint){
if(themeIndex > 9){
return '#C7C9CC';
}
if(typeof tint === 'undefined'){
return themeColor[themeIndex];
}else if(tint > 0){
return getLightColor(themeColor[themeIndex], tint);
}else{
return getDarkColor(themeColor[themeIndex],Math.abs(tint));
}
}
function getStyle(cell){
cell.style = cloneDeep(cell.style);
let backGroundColor = null;
if(cell.style.fill && cell.style.fill.fgColor) {
// 8位字符颜色先转rgb再转16进制颜色
if(cell.style.fill.fgColor.argb){
backGroundColor = transferArgbColor(cell.style.fill.fgColor.argb);
}else if(cell.style.fill.fgColor.hasOwnProperty('theme')){
backGroundColor = transferThemeColor(cell.style.fill.fgColor.theme, cell.style.fill.fgColor.tint);
}else if(cell.style.fill.fgColor.indexed){
backGroundColor = indexedColor[cell.style.fill.fgColor.indexed] || '#C7C9CC';
}else{
backGroundColor = '#C7C9CC';
}
}
if(backGroundColor) {
cell.style.bgcolor = backGroundColor;
}
//*************************************************************************** */
//*********************字体存在背景色******************************
// 字体颜色
let fontColor = null;
if(cell.style.font && cell.style.font.color ) {
if(cell.style.font.color.argb){
fontColor = transferArgbColor(cell.style.font.color.argb);
}else if(cell.style.font.color.hasOwnProperty('theme')){
fontColor = transferThemeColor(cell.style.font.color.theme, cell.style.font.color.tint);
}else if(cell.style.font.color.indexed){
fontColor = indexedColor[cell.style.font.color.indexed] || '#000000';
}else {
fontColor = '#000000';
}
}
if(fontColor) {
cell.style.color = fontColor;
}
// exceljs 对齐的格式转成 x-date-spreedsheet 能识别的对齐格式
if(cell.style.alignment ) {
if(cell.style.alignment.horizontal){
cell.style.align = cell.style.alignment.horizontal;
}
if(cell.style.alignment.vertical){
cell.style.valign = cell.style.alignment.vertical;
}
}
if(cell.style.alignment && cell.style.alignment.wrapText) {
cell.style.textwrap = true;
}
if(cell.style.border){
let styleBorder = {};
Object.keys(cell.style.border).forEach(position =>{
let originBorder = cell.style.border[position];
let bordColor = '#000000';
if(typeof originBorder.color === 'string'){
bordColor = originBorder.color;
}else if(originBorder.color){
if(originBorder.color.argb){
bordColor = transferArgbColor(originBorder.color.argb);
}else if(originBorder.color.hasOwnProperty('theme')){
bordColor = transferThemeColor(originBorder.color.theme, originBorder.color.tint);
}else if(originBorder.color.indexed){
bordColor = indexedColor[originBorder.color.indexed];
}
}
styleBorder[position] = [originBorder.style || 'thin', bordColor];
});
cell.style.border2 = {...cell.style.border};
cell.style.border = styleBorder;
}
if(cell.style.font && cell.style.font.size && typeof cell.style.font.size === 'number'){
cell.style.font.size = Math.round(cell.style.font.size / 1.333333);
}
return cell.style;
}
export function transferExcelToSpreadSheet(workbook, options){
let workbookData = [];
// console.log(workbook, 'workbook');
let sheets = [];
workbook.eachSheet((sheet) => {
sheets.push(sheet);
//console.log(sheet,'sheet');
// 构造x-data-spreadsheet 的 sheet 数据源结构
let sheetData = { name: sheet.name,styles : [], rows: {},cols:{}, merges:[],media:[] };
// 收集合并单元格信息
let mergeAddressData = [];
for(let mergeRange in sheet._merges) {
sheetData.merges.push(sheet._merges[mergeRange].shortRange);
let mergeAddress = {};
// 合并单元格起始地址
mergeAddress.startAddress = sheet._merges[mergeRange].tl;
// 合并单元格终止地址
mergeAddress.endAddress = sheet._merges[mergeRange].br;
// Y轴方向跨度
mergeAddress.YRange = sheet._merges[mergeRange].model.bottom - sheet._merges[mergeRange].model.top;
// X轴方向跨度
mergeAddress.XRange = sheet._merges[mergeRange].model.right - sheet._merges[mergeRange].model.left;
mergeAddressData.push(mergeAddress);
}
transferColumns(sheet,sheetData, options);
// 遍历行
(sheet._rows || []).forEach((row,spreadSheetRowIndex) =>{
sheetData.rows[spreadSheetRowIndex] = { cells: {} };
if(row.height){
sheetData.rows[spreadSheetRowIndex].height = row.height + (options.heightOffset || 0);
}else{
sheetData.rows[spreadSheetRowIndex].height = defaultRowHeight + (options.heightOffset || 0);
}
//includeEmpty = false 不包含空白单元格
(row._cells || []).forEach((cell, spreadSheetColIndex) =>{
sheetData.rows[spreadSheetRowIndex].cells[spreadSheetColIndex] = {};
let mergeAddress = find(mergeAddressData, function(o) { return o.startAddress == cell._address; });
if(mergeAddress && cell.master.address != mergeAddress.startAddress) {
return;
}
if(mergeAddress){
sheetData.rows[spreadSheetRowIndex].cells[spreadSheetColIndex].merge = [mergeAddress.YRange, mergeAddress.XRange];
}
sheetData.rows[spreadSheetRowIndex].cells[spreadSheetColIndex].text = getCellText(cell);
sheetData.styles.push(getStyle(cell));
sheetData.rows[spreadSheetRowIndex].cells[spreadSheetColIndex].style = sheetData.styles.length - 1;
});
});
if(sheetData._media){
sheetData.media = sheetData._media;
}
let tempRowsKeys = Object.keys(sheetData.rows);
sheetData.rows.len = Math.max(+tempRowsKeys[tempRowsKeys.length-1] + 1,
options.hasOwnProperty('minRowLength') ? options.minRowLength : 100);
workbookData.push(sheetData);
});
// console.log(workbookData, 'workbookData');
workbook._worksheets = sheets;
return {
workbookData,
workbookSource: workbook,
medias: workbook.media || []
};
}

View File

@ -1,9 +0,0 @@
export function readOnlyInput(root){
if(root){
let nodes = root.querySelectorAll('input');
for(let node of nodes){
node && !node.readOnly && (node.readOnly = true);
}
document.activeElement && document.activeElement.blur();
}
}

View File

@ -1,767 +0,0 @@
body {
margin: 0;
}
.x-spreadsheet {
font-size: 13px;
line-height: normal;
user-select: none;
-moz-user-select: none;
font-family: 'Lato', 'Source Sans Pro', Roboto, Helvetica, Arial, sans-serif;
box-sizing: content-box;
background: #fff;
-webkit-font-smoothing: antialiased;
}
.x-spreadsheet textarea {
font: 400 13px Arial, 'Lato', 'Source Sans Pro', Roboto, Helvetica, sans-serif;
}
.x-spreadsheet-sheet {
position: relative;
overflow: hidden;
}
.x-spreadsheet-table {
vertical-align: bottom;
}
.x-spreadsheet-tooltip {
font-family: inherit;
position: absolute;
padding: 5px 10px;
color: #fff;
border-radius: 1px;
background: #000000;
font-size: 12px;
z-index: 201;
}
.x-spreadsheet-tooltip:before {
pointer-events: none;
position: absolute;
left: calc(50% - 4px);
top: -4px;
content: "";
width: 8px;
height: 8px;
background: inherit;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
z-index: 1;
box-shadow: 1px 1px 3px -1px rgba(0, 0, 0, 0.3);
}
.x-spreadsheet-color-palette {
padding: 5px;
}
.x-spreadsheet-color-palette table {
margin: 0;
padding: 0;
border-collapse: separate;
border-spacing: 2;
background: #fff;
}
.x-spreadsheet-color-palette table td {
margin: 0;
cursor: pointer;
border: 1px solid transparent;
}
.x-spreadsheet-color-palette table td:hover {
border-color: #ddd;
}
.x-spreadsheet-color-palette table td .x-spreadsheet-color-palette-cell {
width: 16px;
height: 16px;
}
.x-spreadsheet-border-palette {
padding: 6px;
}
.x-spreadsheet-border-palette table {
margin: 0;
padding: 0;
border-collapse: separate;
border-spacing: 0;
background: #fff;
table-layout: fixed;
}
.x-spreadsheet-border-palette table td {
margin: 0;
}
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-left {
border-right: 1px solid #eee;
padding-right: 6px;
}
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell {
width: 30px;
height: 30px;
cursor: pointer;
text-align: center;
}
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell:hover {
background-color: #eee;
}
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-right {
padding-left: 6px;
}
.x-spreadsheet-border-palette .x-spreadsheet-border-palette-right .x-spreadsheet-line-type {
position: relative;
left: 0;
top: -3px;
}
.x-spreadsheet-dropdown {
position: relative;
}
.x-spreadsheet-dropdown .x-spreadsheet-dropdown-content {
position: absolute;
z-index: 200;
background: #fff;
box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15);
}
.x-spreadsheet-dropdown.bottom-left .x-spreadsheet-dropdown-content {
top: calc(100% + 5px);
left: 0;
}
.x-spreadsheet-dropdown.bottom-right .x-spreadsheet-dropdown-content {
top: calc(100% + 5px);
right: 0;
}
.x-spreadsheet-dropdown.top-left .x-spreadsheet-dropdown-content {
bottom: calc(100% + 5px);
left: 0;
}
.x-spreadsheet-dropdown.top-right .x-spreadsheet-dropdown-content {
bottom: calc(100% + 5px);
right: 0;
}
.x-spreadsheet-dropdown .x-spreadsheet-dropdown-title {
padding: 0 5px;
display: inline-block;
}
/* resizer **/
.x-spreadsheet-resizer {
position: absolute;
z-index: 11;
}
.x-spreadsheet-resizer .x-spreadsheet-resizer-hover {
background-color: rgba(75, 137, 255, 0.25);
}
.x-spreadsheet-resizer .x-spreadsheet-resizer-line {
position: absolute;
}
.x-spreadsheet-resizer.horizontal {
cursor: row-resize;
}
.x-spreadsheet-resizer.horizontal .x-spreadsheet-resizer-line {
border-bottom: 2px dashed #4b89ff;
left: 0;
bottom: 0;
}
.x-spreadsheet-resizer.vertical {
cursor: col-resize;
}
.x-spreadsheet-resizer.vertical .x-spreadsheet-resizer-line {
border-right: 2px dashed #4b89ff;
top: 0;
right: 0;
}
/* scrollbar */
.x-spreadsheet-scrollbar {
position: absolute;
bottom: 0;
right: 0;
background-color: #f4f5f8;
opacity: 0.9;
z-index: 12;
}
.x-spreadsheet-scrollbar.horizontal {
right: 15px;
overflow-x: scroll;
overflow-y: hidden;
}
.x-spreadsheet-scrollbar.horizontal > div {
height: 1px;
background: #ddd;
}
.x-spreadsheet-scrollbar.vertical {
bottom: 15px;
overflow-x: hidden;
overflow-y: scroll;
}
.x-spreadsheet-scrollbar.vertical > div {
width: 1px;
background: #ddd;
}
/* @{css-prefix}-overlayer */
.x-spreadsheet-overlayer {
position: absolute;
left: 0;
top: 0;
z-index: 10;
}
.x-spreadsheet-overlayer .x-spreadsheet-overlayer-content {
position: absolute;
overflow: hidden;
pointer-events: none;
width: 100%;
height: 100%;
}
.x-spreadsheet-editor,
.x-spreadsheet-selector {
box-sizing: content-box;
position: absolute;
overflow: hidden;
pointer-events: none;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* @{css-prefix}-selector */
.x-spreadsheet-selector .hide-input {
position: absolute;
z-index: 0;
}
.x-spreadsheet-selector .hide-input input {
padding: 0;
width: 0;
border: none!important;
}
.x-spreadsheet-selector .x-spreadsheet-selector-area {
position: absolute;
border: 2px solid #4b89ff;
background: rgba(75, 137, 255, 0.1);
z-index: 5;
}
.x-spreadsheet-selector .x-spreadsheet-selector-clipboard,
.x-spreadsheet-selector .x-spreadsheet-selector-autofill {
position: absolute;
background: transparent;
z-index: 100;
}
.x-spreadsheet-selector .x-spreadsheet-selector-clipboard {
border: 2px dashed #4b89ff;
}
.x-spreadsheet-selector .x-spreadsheet-selector-autofill {
border: 1px dashed rgba(0, 0, 0, 0.45);
}
.x-spreadsheet-selector .x-spreadsheet-selector-corner {
pointer-events: auto;
position: absolute;
cursor: crosshair;
font-size: 0;
height: 5px;
width: 5px;
right: -5px;
bottom: -5px;
border: 2px solid #ffffff;
background: #4b89ff;
}
.x-spreadsheet-editor {
z-index: 20;
}
.x-spreadsheet-editor .x-spreadsheet-editor-area {
position: absolute;
text-align: left;
border: 2px solid #4b89ff;
line-height: 0;
z-index: 100;
pointer-events: auto;
}
.x-spreadsheet-editor .x-spreadsheet-editor-area textarea {
box-sizing: content-box;
border: none;
padding: 0 3px;
outline: none;
resize: none;
text-align: start;
overflow-y: hidden;
font: 400 13px Arial, 'Lato', 'Source Sans Pro', Roboto, Helvetica, sans-serif;
color: inherit;
white-space: normal;
word-wrap: break-word;
line-height: 22px;
margin: 0;
}
.x-spreadsheet-editor .x-spreadsheet-editor-area .textline {
overflow: hidden;
visibility: hidden;
position: fixed;
top: 0;
left: 0;
}
.x-spreadsheet-item {
user-select: none;
background: 0;
border: 1px solid transparent;
outline: none;
height: 26px;
color: rgba(0, 0, 0, 0.9);
line-height: 26px;
list-style: none;
padding: 2px 10px;
cursor: default;
text-align: left;
overflow: hidden;
}
.x-spreadsheet-item.disabled {
pointer-events: none;
opacity: 0.5;
}
.x-spreadsheet-item:hover,
.x-spreadsheet-item.active {
background: rgba(0, 0, 0, 0.05);
}
.x-spreadsheet-item.divider {
height: 0;
padding: 0;
margin: 5px 0;
border: none;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
.x-spreadsheet-item .label {
float: right;
opacity: 0.65;
font-size: 1em;
}
.x-spreadsheet-item.state,
.x-spreadsheet-header.state {
padding-left: 35px!important;
position: relative;
}
.x-spreadsheet-item.state:before,
.x-spreadsheet-header.state:before {
content: '';
position: absolute;
width: 10px;
height: 10px;
left: 12px;
top: calc(50% - 5px);
background: rgba(0, 0, 0, 0.08);
border-radius: 2px;
}
.x-spreadsheet-item.state.checked:before,
.x-spreadsheet-header.state.checked:before {
background: #4b89ff;
}
.x-spreadsheet-checkbox {
position: relative;
display: inline-block;
backface-visibility: hidden;
outline: 0;
vertical-align: baseline;
font-style: normal;
font-size: 1rem;
line-height: 1em;
}
.x-spreadsheet-checkbox > input {
position: absolute;
top: 0;
left: 0;
opacity: 0!important;
outline: 0;
z-index: -1;
}
.x-spreadsheet-suggest,
.x-spreadsheet-contextmenu,
.x-spreadsheet-sort-filter {
position: absolute;
box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15);
background: #fff;
z-index: 100;
width: 260px;
pointer-events: auto;
overflow: auto;
}
.x-spreadsheet-suggest {
width: 200px;
}
.x-spreadsheet-filter {
border: 1px solid #e9e9e9;
font-size: 12px;
margin: 10px;
}
.x-spreadsheet-filter .x-spreadsheet-header {
padding: 0.5em 0.75em;
background: #f8f8f9;
border-bottom: 1px solid #e9e9e9;
border-left: 1px solid transparent;
}
.x-spreadsheet-filter .x-spreadsheet-body {
height: 200px;
overflow-y: auto;
}
.x-spreadsheet-filter .x-spreadsheet-body .x-spreadsheet-item {
height: 20px;
line-height: 20px;
}
.x-spreadsheet-sort-filter .x-spreadsheet-buttons {
margin: 10px;
}
.x-spreadsheet-bottombar {
height: 40px;
padding: 0 30px;
text-align: left;
background: #f5f6f7;
display: flex;
}
.x-spreadsheet-bottombar {
position: relative;
border-top: 1px solid #e0e2e4;
}
.x-spreadsheet-bottombar .x-spreadsheet-menu > li {
line-height: 40px;
height: 40px;
padding-top: 0;
padding-bottom: 0;
vertical-align: middle;
border-right: 1px solid #e8eaed;
}
.x-spreadsheet-menu {
display: flex;
overflow-x: auto;
list-style: none;
margin: 0;
padding: 0;
user-select: none;
}
.x-spreadsheet-menu > li {
float: left;
line-height: 1.25em;
padding: 0.785em 1em;
margin: 0;
vertical-align: middle;
text-align: left;
font-weight: 400;
color: #80868b;
white-space: nowrap;
cursor: pointer;
transition: all 0.3s;
font-weight: bold;
}
.x-spreadsheet-menu > li.active {
background-color: #fff;
color: rgba(0, 0, 0, 0.65);
}
.x-spreadsheet-menu > li .x-spreadsheet-dropdown {
display: inline-block;
}
.x-spreadsheet-print {
position: absolute;
left: 0;
top: 0;
z-index: 100;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.x-spreadsheet-print-bar {
background: #424242;
height: 60px;
line-height: 60px;
padding: 0 30px;
}
.x-spreadsheet-print-bar .-title {
color: #fff;
font-weight: bold;
font-size: 1.2em;
float: left;
}
.x-spreadsheet-print-bar .-right {
float: right;
margin-top: 12px;
}
.x-spreadsheet-print-content {
display: flex;
flex: auto;
flex-direction: row;
background: #d0d0d0;
height: calc(100% - 60px);
}
.x-spreadsheet-print-content .-sider {
flex: 0 0 300px;
width: 300px;
border-left: 2px solid #ccc;
background: #fff;
}
.x-spreadsheet-print-content .-content {
flex: auto;
overflow-x: auto;
overflow-y: scroll;
height: 100%;
}
.x-spreadsheet-canvas-card-wraper {
margin: 40px 20px;
}
.x-spreadsheet-canvas-card {
background: #fff;
margin: auto;
page-break-before: auto;
page-break-after: always;
box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 3px rgba(0, 0, 0, 0.12), 0 4px 5px 0 rgba(0, 0, 0, 0.2);
}
.x-spreadsheet-calendar {
color: rgba(0, 0, 0, 0.65);
background: #ffffff;
user-select: none;
}
.x-spreadsheet-calendar .calendar-header {
font-weight: 700;
line-height: 30px;
text-align: center;
width: 100%;
float: left;
background: #f9fafb;
}
.x-spreadsheet-calendar .calendar-header .calendar-header-left {
padding-left: 5px;
float: left;
}
.x-spreadsheet-calendar .calendar-header .calendar-header-right {
float: right;
}
.x-spreadsheet-calendar .calendar-header .calendar-header-right a {
padding: 3px 0;
margin-right: 2px;
border-radius: 2px;
}
.x-spreadsheet-calendar .calendar-header .calendar-header-right a:hover {
background: rgba(0, 0, 0, 0.08);
}
.x-spreadsheet-calendar .calendar-body {
border-collapse: collapse;
border-spacing: 0;
}
.x-spreadsheet-calendar .calendar-body th,
.x-spreadsheet-calendar .calendar-body td {
width: 14.28571429%;
min-width: 32px;
text-align: center;
font-weight: 700;
line-height: 30px;
padding: 0;
}
.x-spreadsheet-calendar .calendar-body td > .cell:hover {
background: #ecf6fd;
}
.x-spreadsheet-calendar .calendar-body td > .cell.active,
.x-spreadsheet-calendar .calendar-body td > .cell.active:hover {
background: #ecf6fd;
color: #2185D0;
}
.x-spreadsheet-calendar .calendar-body td > .cell.disabled {
pointer-events: none;
opacity: 0.5;
}
.x-spreadsheet-datepicker {
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2);
position: absolute;
left: 0;
top: calc(100% + 5px);
z-index: 10;
width: auto;
}
.x-spreadsheet-buttons {
display: flex;
justify-content: flex-end;
}
.x-spreadsheet-buttons .x-spreadsheet-button {
margin-left: 8px;
}
.x-spreadsheet-button {
display: inline-block;
border-radius: 3px;
line-height: 1em;
min-height: 1em;
white-space: nowrap;
text-align: center;
cursor: pointer;
font-size: 1em;
font-weight: 700;
padding: 0.75em 1em;
color: rgba(0, 0, 0, 0.6);
background: #E0E1E2;
text-decoration: none;
font-family: "Lato", "proxima-nova", "Helvetica Neue", Arial, sans-serif;
outline: none;
vertical-align: baseline;
zoom: 1;
user-select: none;
transition: all 0.1s linear;
}
.x-spreadsheet-button.active,
.x-spreadsheet-button:hover {
background-color: #C0C1C2;
color: rgba(0, 0, 0, 0.8);
}
.x-spreadsheet-button.primary {
color: #fff;
background-color: #2185D0;
}
.x-spreadsheet-button.primary:hover,
.x-spreadsheet-button.primary.active {
color: #fff;
background-color: #1678c2;
}
.x-spreadsheet-form-input {
font-size: 1em;
position: relative;
font-weight: 400;
display: inline-flex;
color: rgba(0, 0, 0, 0.87);
}
.x-spreadsheet-form-input input {
z-index: 1;
margin: 0;
max-width: 100%;
flex: 1 0 auto;
outline: 0;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
text-align: left;
line-height: 30px;
height: 30px;
padding: 0 8px;
background: #fff;
border: 1px solid #e9e9e9;
border-radius: 3px;
transition: box-shadow 0.1s ease, border-color 0.1s ease;
box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06);
}
.x-spreadsheet-form-input input:focus {
border-color: #4b89ff;
box-shadow: inset 0 1px 2px rgba(75, 137, 255, 0.2);
}
.x-spreadsheet-form-select {
position: relative;
display: inline-block;
background: #fff;
border: 1px solid #e9e9e9;
border-radius: 2px;
cursor: pointer;
color: rgba(0, 0, 0, 0.87);
user-select: none;
box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06);
}
.x-spreadsheet-form-select .input-text {
text-overflow: ellipsis;
white-space: nowrap;
min-width: 60px;
width: auto;
height: 30px;
line-height: 30px;
padding: 0 8px;
}
.x-spreadsheet-form-fields {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.x-spreadsheet-form-fields .x-spreadsheet-form-field {
flex: 0 1 auto;
}
.x-spreadsheet-form-fields .x-spreadsheet-form-field .label {
display: inline-block;
margin: 0 10px 0 0;
}
.x-spreadsheet-form-field {
display: block;
vertical-align: middle;
margin-left: 10px;
margin-bottom: 10px;
}
.x-spreadsheet-form-field:first-child {
margin-left: 0;
}
.x-spreadsheet-form-field.error .x-spreadsheet-form-select,
.x-spreadsheet-form-field.error input {
border-color: #f04134;
}
.x-spreadsheet-form-field .tip {
color: #f04134;
font-size: 0.9em;
}
.x-spreadsheet-dimmer {
display: none;
position: absolute;
top: 0 !important;
left: 0 !important;
width: 100%;
height: 100%;
text-align: center;
vertical-align: middle;
background-color: rgba(0, 0, 0, 0.6);
opacity: 0;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-duration: 0.5s;
animation-duration: 0.5s;
transition: background-color 0.5s linear;
user-select: none;
z-index: 1000;
}
.x-spreadsheet-dimmer.active {
display: block;
opacity: 1;
}
form fieldset {
border: none;
}
form fieldset label {
display: block;
margin-bottom: 0.5em;
font-size: 1em;
color: #666;
}
form fieldset select {
font-size: 1.1em;
width: 100%;
background-color: #fff;
border: none;
border-bottom: 2px solid #ddd;
padding: 0.5em 0.85em;
border-radius: 2px;
}
.x-spreadsheet-modal,
.x-spreadsheet-toast {
font-size: 13px;
position: fixed;
z-index: 1001;
text-align: left;
line-height: 1.25em;
min-width: 360px;
color: rgba(0, 0, 0, 0.87);
font-family: 'Lato', 'Source Sans Pro', Roboto, Helvetica, Arial, sans-serif;
border-radius: 4px;
border: 1px solid rgba(0, 0, 0, 0.1);
background-color: #fff;
background-clip: padding-box;
box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 8px;
}
.x-spreadsheet-toast {
background-color: rgba(255, 255, 255, 0.85);
}
.x-spreadsheet-modal-header,
.x-spreadsheet-toast-header {
font-weight: 600;
background-clip: padding-box;
background-color: rgba(255, 255, 255, 0.85);
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 4px 4px 0 0;
}
.x-spreadsheet-toast-header {
color: #F2711C;
}
.x-spreadsheet-modal-header {
border-bottom: 1px solid #e0e2e4;
background: rgba(0, 0, 0, 0.08);
font-size: 1.0785em;
}
.x-spreadsheet-modal-header,
.x-spreadsheet-modal-content,
.x-spreadsheet-toast-header,
.x-spreadsheet-toast-content {
padding: 0.75em 1em;
}
.x-spreadsheet-menu li:first-child {
display: none;
}
.vue-office-excel {
height: 100%;
}

View File

@ -1,187 +0,0 @@
<script>
import {defineComponent, ref, onMounted, onBeforeUnmount, watch, nextTick} from 'vue-demi';
import Spreadsheet from 'x-data-spreadsheet';
import {getData, readExcelData, transferExcelToSpreadSheet} from './excel';
import {renderImage, clearCache} from './media';
import {readOnlyInput} from './hack';
import {debounce} from 'lodash';
import {download as downloadFile} from '../../../utils/url';
const defaultOptions = {
xls: false,
minColLength: 20
};
export default defineComponent({
name: 'VueOfficeExcel',
props: {
src: [String, ArrayBuffer, Blob],
requestOptions: {
type: Object,
default: () => ({})
},
options: {
type: Object,
default: () => ({
...defaultOptions
})
}
},
emits: ['rendered', 'error'],
setup(props, {emit}) {
const wrapperRef = ref(null);
const rootRef = ref(null);
let workbookDataSource = {
_worksheets:[]
};
let mediasSource = [];
let sheetIndex = 0;
let ctx = null;
let xs = null;
let offset = null;
let fileData = null;
function renderExcel(buffer) {
fileData = buffer;
readExcelData(buffer, props.options.xls).then(workbook => {
if (!workbook._worksheets || workbook._worksheets.length === 0) {
throw new Error('未获取到数据,可能文件格式不正确或文件已损坏');
}
if(props.options.beforeTransformData && typeof props.options.beforeTransformData === 'function' ){
workbook = props.options.beforeTransformData(workbook);
}
let {workbookData, medias, workbookSource} = transferExcelToSpreadSheet(workbook, {...defaultOptions, ...props.options});
if(props.options.transformData && typeof props.options.transformData === 'function' ){
workbookData = props.options.transformData(workbookData);
}
mediasSource = medias;
workbookDataSource = workbookSource;
offset = null;
sheetIndex = 0;
clearCache();
xs.loadData(workbookData);
renderImage(ctx, mediasSource, workbookDataSource._worksheets[sheetIndex], offset, props.options);
emit('rendered');
//clearoffset
}).catch(e => {
console.warn(e);
mediasSource = [];
workbookDataSource = {
_worksheets:[]
};
clearCache();
xs && xs.loadData({});
emit('error', e);
});
}
const observerCallback = debounce(readOnlyInput, 200).bind(this,rootRef.value);
const observer = new MutationObserver(observerCallback);
const observerConfig = { attributes: true, childList: true, subtree: true };
onMounted(() => {
nextTick(()=>{
observer.observe(rootRef.value, observerConfig);
observerCallback(rootRef);
xs = new Spreadsheet(rootRef.value, {
mode: 'read',
showToolbar: false,
showContextmenu: props.options.showContextmenu || false,
view: {
height: () => wrapperRef.value && wrapperRef.value.clientHeight || 300,
width: () => wrapperRef.value && wrapperRef.value.clientWidth || 1200,
},
row: {
height: 24,
len: 100
},
col: {
len: 26,
width: 80,
indexWidth: 60,
minWidth: 60,
},
autoFocus: false
}).loadData({});
let swapFunc = xs.bottombar.swapFunc;
xs.bottombar.swapFunc = function (index) {
swapFunc.call(xs.bottombar, index);
sheetIndex = index;
setTimeout(()=>{
xs.reRender();
renderImage(ctx, mediasSource, workbookDataSource._worksheets[sheetIndex], offset, props.options);
});
};
let clear = xs.sheet.editor.clear;
xs.sheet.editor.clear = function (...args){
clear.apply(xs.sheet.editor, args);
setTimeout(()=>{
renderImage(ctx, mediasSource, workbookDataSource._worksheets[sheetIndex], offset, props.options);
});
};
let setOffset = xs.sheet.editor.setOffset;
xs.sheet.editor.setOffset = function (...args){
setOffset.apply(xs.sheet.editor, args);
offset = args[0];
renderImage(ctx, mediasSource, workbookDataSource._worksheets[sheetIndex], offset, props.options);
};
const canvas = rootRef.value.querySelector('canvas');
ctx = canvas.getContext('2d');
if (props.src) {
getData(props.src, props.requestOptions).then(renderExcel).catch(e => {
mediasSource = [];
workbookDataSource = {
_worksheets:[]
};
xs.loadData({});
emit('error', e);
});
}
});
});
onBeforeUnmount(()=>{
observer.disconnect();
xs = null;
});
watch(() => props.src, () => {
if (props.src) {
getData(props.src, props.requestOptions).then(renderExcel).catch(e => {
mediasSource = [];
workbookDataSource = {
_worksheets:[]
};
xs.loadData({});
emit('error', e);
});
} else {
mediasSource = [];
workbookDataSource = {
_worksheets:[]
};
xs.loadData({});
emit('error', new Error('src属性不能为空'));
}
});
function save(fileName){
downloadFile(fileName || `vue-office-excel-${new Date().getTime()}.xlsx`,fileData);
}
return {
wrapperRef,
rootRef,
save
};
}
});
</script>
<template>
<div class="vue-office-excel" ref="wrapperRef">
<div class="vue-office-excel-main" ref="rootRef"></div>
</div>
</template>
<style lang="less">
</style>

View File

@ -1,136 +0,0 @@
let cache = [];
export function renderImage(ctx, medias, sheet, offset, options={}){
// console.log('medias', medias);
// console.log('sheet', sheet);
// console.log('offset', offset)
if(sheet && sheet._media.length){
sheet._media.forEach(media => {
let {imageId, range, type} = media;
if(type === 'image'){
let position = calcPosition(sheet,range,offset, options);
drawImage(ctx,imageId, medias[imageId], position);
}
});
}
}
let clipWidth = 60; //左侧序号列宽
let clipHeight = 25; //顶部序号行高
let defaultColWidth = 80;
let defaultRowHeight = 24;
let devicePixelRatio = window.devicePixelRatio;
function calcPosition(sheet, range, offset, options){
let {widthOffset, heightOffset} = options;
let {tl, br, ext} = range;
let {nativeCol=0, nativeColOff=0, nativeRow=0, nativeRowOff=0} = tl || {};
let basicX = clipWidth;
let basicY = clipHeight;
for(let i=0; i < nativeCol; i++){
basicX += sheet?._columns?.[i]?.width*6 || defaultColWidth;
basicX += widthOffset || 0;
}
for(let i=0; i < nativeRow; i++){
basicY += sheet?._rows?.[i]?.height || defaultRowHeight;
basicY += heightOffset || 0;
}
let x = basicX + nativeColOff/12700;
let y = basicY + nativeRowOff/12700;
let {
nativeCol: nativeColEnd=0,
nativeColOff: nativeColOffEnd=0,
nativeRow: nativeRowEnd=0,
nativeRowOff: nativeRowOffEnd=0
} = br||{};
let width =0;
if(nativeCol === nativeColEnd){
width = (nativeColOffEnd - nativeColOff) / 12700;
}else if(br) {
width = (sheet?._columns?.[nativeCol]?.width*6 || defaultColWidth) - nativeColOff/12700;
for(let i = nativeCol+1; i < nativeColEnd; i++){
width += sheet?._columns?.[i]?.width*6 || defaultColWidth;
}
width += nativeColOffEnd / 12700;
}else if(ext?.width){
width = ext.width / 1.333333;
}
let height;
if(nativeRow === nativeRowEnd){
height = (nativeRowOffEnd - nativeRowOff) / 12700;
}else if(br) {
height = (sheet?._rows?.[nativeRow]?.height || defaultRowHeight) - nativeRowOff/12700;
for(let i = nativeRow+1; i < nativeRowEnd; i++){
height += sheet?._rows?.[i]?.height || defaultRowHeight;
}
height += nativeRowOffEnd / 12700;
}else if(ext?.height){
height = ext.height / 1.333333;
}
return {
x: (x - (offset?.scroll?.x || 0)) * devicePixelRatio,
y: (y - (offset?.scroll?.y || 0)) * devicePixelRatio,
width: width * devicePixelRatio,
height: height * devicePixelRatio
};
}
export function clearCache(){
cache = [];
}
function drawImage(ctx,index, data, position){
getImage(index, data).then(image=>{
let sx = 0;
let sy = 0;
let sWidth = image.width;
let sHeight = image.height;
let dx = position.x;
let dy = position.y;
let dWidth = position.width;
let dHeight = position.height;
let scaleX = dWidth / sWidth;
let scaleY = dHeight / sHeight;
if(dx < clipWidth * devicePixelRatio){
let diff = clipWidth * devicePixelRatio - dx;
dx = clipWidth * devicePixelRatio;
dWidth -= diff;
sWidth -= diff/scaleX;
sx += diff/scaleX;
}
if(dy < clipHeight * devicePixelRatio){
let diff = clipHeight * devicePixelRatio - dy;
dy = clipHeight * devicePixelRatio;
dHeight -= diff;
sHeight -= diff/scaleY;
sy += diff/scaleY;
}
// console.log('=>', sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
}).catch(e=>{
console.error(e);
});
}
function getImage(index, data){
return new Promise(((resolve, reject) => {
if(cache[index]){
return resolve(cache[index]);
}
const {buffer} = data.buffer;
let blob = new Blob([buffer], { type: 'image/' + data.extension});
let url = URL.createObjectURL(blob);
let image = new Image();
image.src = url;
image.onload = function (){
resolve(image);
cache[index] = image;
};
image.onerror = function (e){
reject(e);
};
}));
}

View File

@ -1,60 +0,0 @@
import { defineConfig } from 'vite';
import { createVuePlugin } from 'vite-plugin-vue2';
import vue3 from '@vitejs/plugin-vue';
import * as compiler from '@vue/compiler-sfc';
import { isVue2 } from 'vue-demi';
const { resolve } = require('path');
import babel from '@rollup/plugin-babel';
export default defineConfig({
plugins: [
isVue2
? createVuePlugin()
: vue3({
compiler: compiler
})
],
build: {
minify: 'terser',
target: 'es2015',
outDir: 'lib/v' + (isVue2 ? '2' : '3'),
lib: {
entry: resolve(__dirname, 'index.js'), //指定组件编译入口文件
name: 'vue-office-excel',
fileName: 'vue-office-excel',
},
optimizeDeps: {
exclude: ['vue-demi']
},
rollupOptions: {
external: ['vue-demi','vue'],
output: {
globals: {
vue: 'Vue',
'vue-demi': 'VueDemi'
},
},
plugins: [
babel({
extensions: ['.js', '.ts', '.vue'],
babelHelpers: 'runtime',
plugins: [
'@babel/plugin-transform-runtime',
'@babel/plugin-transform-template-literals'
],
presets: [
[
'@babel/preset-env',
{
useBuiltIns: false,
targets: {
chrome: '40'
},
},
],
],
}),
],
},
},
});

View File

@ -1 +0,0 @@
registry=https://registry.npmjs.org

View File

@ -1,9 +0,0 @@
declare const VueOfficePdf: {
install?: (vue: any) => void;
src: string|ArrayBuffer|Blob;
rerender?: () => any;
staticFileUrl?: string,
requestOptions?: any;
options?: any
};
export default VueOfficePdf;

View File

@ -1,7 +0,0 @@
import VueOfficePdf from './src/main.vue';
VueOfficePdf.install = function (Vue) {
Vue.component(VueOfficePdf.name, VueOfficePdf);
};
export default VueOfficePdf;

View File

@ -1,48 +0,0 @@
{
"name": "@vue-office/pdf",
"version": "1.6.5",
"description": "",
"main": "lib/index.js",
"files": [
"lib/"
],
"scripts": {
"clean": "rimraf lib",
"copyFile2": "cp lib/v2/vue-office-pdf.umd.js lib/v2/index.js",
"copyFile3": "cp lib/v3/vue-office-pdf.umd.js lib/v3/index.js",
"copyReadme": "cp ../../../README.md README.md",
"copyType": "cp index.d.ts lib/index.d.ts",
"copyScripts": "mkdir lib/script/ && cp ../../script/postinstall.js lib/script/postinstall.js && cp ../../script/switch-cli.js lib/script/switch-cli.js && cp ../../script/utils.js lib/script/utils.js",
"build:2": "npx vue-demi-switch 2 vue2 && vite build && npm run copyFile2",
"build:3": "npx vue-demi-switch 3 vue3 && vite build && npm run copyFile3",
"build": "npm run clean && npm run build:2 && npm run build:3 && npm run copyScripts && npm run copyReadme && npm run copyType",
"postinstall": "node lib/script/postinstall.js"
},
"peerDependencies": {
"@vue/composition-api": "^1.7.1",
"vue": "^2.0.0 || >=3.0.0",
"vue-demi": "^0.14.6"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
},
"repository": {
"type": "git",
"url": "git@github.com:501351981/vue-office.git"
},
"keywords": [
"vue",
"docx",
"pdf",
"ppt",
"excel",
"docx-preview",
"excel-preview",
"pdf-preview"
],
"license": "MIT",
"author": "微信: _hit757_",
"gitHead": "d20568113bec480f6ca72924f6d0c1e3b0f1fe15"
}

View File

@ -1,223 +0,0 @@
<script>
import { defineComponent, ref, onMounted, watch, onBeforeUnmount } from 'vue-demi';
import workerStr from './worker?raw';
import pdfjsLib from './pdf?raw';
import { download as downloadFile, getUrl, loadScript } from '../../../utils/url';
import { base64_encode } from '../../../utils/base64';
import omit from 'lodash/omit';
const pdfJsLibSrc = `data:text/javascript;base64,${(base64_encode(pdfjsLib))}`;
const PdfJsWorkerSrc = `data:text/javascript;base64,${(base64_encode(workerStr))}`;
let pdfJsLibLoaded = false;
let workerLoaded = false;
export default defineComponent({
name: 'VueOfficePdf',
props: {
src: [String, ArrayBuffer, Blob],
requestOptions: {
type: Object,
default: () => ({})
},
staticFileUrl: {
type: String,
default: 'https://unpkg.com/pdfjs-dist@3.1.81/'
},
options: {
type: Object,
default: () => ({})
}
},
emits: ['rendered', 'error'],
setup(props, { emit }) {
let pdfDocument = null;
let loadingTask = null;
const wrapperRef = ref(null);
const rootRef = ref([]);
const numPages = ref(0);
const lazySize = 5;
let loopCheckTimer = null;
onBeforeUnmount(()=>{
if(pdfDocument === null){
return;
}
pdfDocument.destroy();
pdfDocument = null;
loadingTask = null;
loopCheckTimer && clearTimeout(loopCheckTimer);
});
function installPdfScript() {
return loadScript(pdfJsLibSrc).then(() => {
if (window.pdfjsLib && !workerLoaded) {
workerLoaded = true;
window.pdfjsLib.GlobalWorkerOptions.workerSrc = PdfJsWorkerSrc;
} else {
return Promise.reject('window.pdfjsLib未找到');
}
});
}
function waitPdfjsLoad(){
return new Promise((resolve)=>{
const loopCheck = () =>{
if(window.pdfjsLib) {
resolve();
}else{
loopCheckTimer = setTimeout(loopCheck, 10);
}
};
loopCheck();
});
}
function checkPdfLib() {
if (window.pdfjsLib) {
return Promise.resolve();
}
if(!pdfJsLibLoaded){
pdfJsLibLoaded = true;
return installPdfScript();
}else{
return waitPdfjsLoad();
}
}
function init() {
if (!props.src) {
numPages.value = 0;
return;
}
loadingTask = window.pdfjsLib.getDocument({
url: getUrl(props.src),
httpHeaders: props.requestOptions && props.requestOptions.headers,
withCredentials: props.requestOptions && props.requestOptions.withCredentials,
cMapUrl: `${props.staticFileUrl.endsWith('/') ? props.staticFileUrl : props.staticFileUrl + '/'}cmaps/`,
cMapPacked: true,
enableXfa: true,
...omit(props.options, ['width'])
});
loadingTask.promise.then((pdf) => {
pdfDocument && pdfDocument.destroy();
pdfDocument = pdf;
numPages.value = props.options.lazy ? Math.min(pdfDocument.numPages, lazySize) : pdfDocument.numPages;
setTimeout(()=>{
renderPage(1);
});
}).catch((e) => {
emit('error', e);
});
}
function onScrollPdf(e) {
if(!props.options.lazy){
return;
}
const { scrollTop, scrollHeight, clientHeight } = e.target;
if (scrollTop + clientHeight >= scrollHeight) {
if (numPages.value >= pdfDocument.numPages) {
return;
}
let oldNum = numPages.value;
numPages.value = Math.min(pdfDocument.numPages, oldNum + lazySize);
if (numPages.value > oldNum) {
renderPage(oldNum + 1);
}
}
}
function renderPage(num) {
pdfDocument.getPage(num).then((pdfPage) => {
const viewport = pdfPage.getViewport({ scale: 2 });
const outputScale = window.devicePixelRatio > 2 ? 1.5 : 2;
const canvas = rootRef.value[num - 1];
const ctx = canvas.getContext('2d');
canvas.width = Math.floor(viewport.width * outputScale);
canvas.height = Math.floor(viewport.height * outputScale);
let domWidth = Math.floor(viewport.width);
let domHeight = Math.floor(viewport.height);
if (props.options.width) {
let scale = props.options.width / domWidth;
domWidth = Math.floor(props.options.width);
domHeight = Math.floor(domHeight * scale);
}
let wrapperWidth = wrapperRef.value.getBoundingClientRect().width - 20;
if (domWidth > wrapperWidth) {
let scale = wrapperWidth / domWidth;
domWidth = Math.floor(wrapperWidth);
domHeight = Math.floor(domHeight * scale);
}
canvas.style.width = domWidth + 'px';
canvas.style.height = domHeight + 'px';
const transform = outputScale !== 1
? [outputScale, 0, 0, outputScale, 0, 0]
: null;
const renderTask = pdfPage.render({
canvasContext: ctx,
transform,
viewport
});
renderTask.promise.then(() => {
if (numPages.value > num) {
renderPage(num + 1);
} else {
emit('rendered');
}
}).catch((e) => {
emit('error', e);
});
}).catch((e) => {
emit('error', e);
});
}
function rerender(){
renderPage(1);
}
onMounted(() => {
if (props.src) {
checkPdfLib().then(init).catch(e => {
console.warn(e);
});
}
});
watch(() => props.src, () => {
checkPdfLib().then(init).catch(e => {
console.warn(e);
});
});
function save(fileName) {
pdfDocument && pdfDocument._transport && pdfDocument._transport.getData().then(fileData => {
downloadFile(fileName || `vue-office-pdf-${new Date().getTime()}.pdf`, fileData.buffer);
});
}
return {
wrapperRef,
rootRef,
numPages,
save,
onScrollPdf,
rerender
};
}
});
</script>
<template>
<div class="vue-office-pdf" ref="vue-office-pdf" style="text-align: center;overflow-y: auto;" @scroll="onScrollPdf">
<div v-if="numPages" ref="wrapperRef" class="vue-office-pdf-wrapper" style="background: gray; padding: 30px 0;position: relative;">
<canvas v-for="page in numPages" ref="rootRef" :key="page" style="width:100%" />
<slot></slot>
</div>
</div>
</template>
<style lang="less">
</style>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,37 +0,0 @@
import { defineConfig } from 'vite';
import { createVuePlugin } from 'vite-plugin-vue2';
import vue3 from '@vitejs/plugin-vue';
import * as compiler from '@vue/compiler-sfc';
import { isVue2 } from 'vue-demi';
const { resolve } = require('path');
export default defineConfig({
plugins: [
isVue2
? createVuePlugin()
: vue3({
compiler: compiler
}),
],
build: {
target: 'es2015',
outDir: 'lib/v' + (isVue2 ? '2' : '3'),
lib: {
entry: resolve(__dirname, 'index.js'), //指定组件编译入口文件
name: 'vue-office-pdf',
fileName: 'vue-office-pdf',
},
optimizeDeps: {
exclude: ['vue-demi']
},
rollupOptions: {
external: ['vue-demi','vue'],
output: {
globals: {
vue: 'Vue',
'vue-demi': 'VueDemi'
},
},
},
},
});

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More