fix: 粘贴excel数据超过表格本身范围时报错

This commit is contained in:
pipipi-pikachu 2021-07-20 22:18:41 +08:00
parent c8e7360312
commit 2391f56f20
5 changed files with 36 additions and 12612 deletions

1
.gitignore vendored
View File

@ -1,7 +1,6 @@
.DS_Store .DS_Store
node_modules node_modules
/dist /dist
*.lock
# local env files # local env files
.env.local .env.local

View File

@ -53,29 +53,20 @@ export const pasteCustomClipboardString = (text: string) => {
return clipboardData return clipboardData
} }
/** // 尝试解析剪贴板内容是否为Excel表格或类似的数据格式
* exlc表格类型 export const pasteExcelClipboardString = (text: string): string[][] | boolean => {
* @param text const lines: string[] = text.split('\r\n')
* @returns
*/ if (lines[lines.length - 1] === '') lines.pop()
export const exlcTesting = (text: string): string[][] | boolean => {
// 判定一下是不是exl格式 let colCount = -1
const lineList: string[] = text.split('\r\n') const data: string[][] = []
// 按照\n拆分表格 最后会多出一个空字串 for (const index in lines) {
if (lineList[lineList.length - 1] === '') { data[index] = lines[index].split('\t')
lineList.splice(length - 1, 1)
if (data[index].length === 1) return false
if (colCount === -1) colCount = data[index].length
else if (colCount !== data[index].length) return false
} }
let tNum = -1 return data
const exlc: string[][] = []
for (const index in lineList) {
exlc[index] = lineList[index].split('\t')
if (exlc[index].length === 1) return false
if (tNum === -1) {
tNum = exlc[index].length
}
else if (tNum !== exlc[index].length) {
return false
}
}
return exlc
} }

View File

@ -12,7 +12,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, onUnmounted, ref, watch } from 'vue' import { defineComponent, onUnmounted, ref, watch } from 'vue'
import { pasteCustomClipboardString, exlcTesting } from '@/utils/clipboard' import { pasteCustomClipboardString, pasteExcelClipboardString } from '@/utils/clipboard'
export default defineComponent({ export default defineComponent({
name: 'custom-textarea', name: 'custom-textarea',
@ -58,16 +58,16 @@ export default defineComponent({
if (clipboardDataFirstItem && clipboardDataFirstItem.kind === 'string' && clipboardDataFirstItem.type === 'text/plain') { if (clipboardDataFirstItem && clipboardDataFirstItem.kind === 'string' && clipboardDataFirstItem.type === 'text/plain') {
clipboardDataFirstItem.getAsString(text => { clipboardDataFirstItem.getAsString(text => {
// exlc const clipboardData = pasteCustomClipboardString(text)
const exlc = exlcTesting(text) if (typeof clipboardData === 'object') return
if (exlc) {
emit('updateExlc', exlc) const excelData = pasteExcelClipboardString(text)
if (textareaRef.value) textareaRef.value.innerHTML = exlc[0][0] if (excelData) {
emit('insertExcelData', excelData)
if (textareaRef.value) textareaRef.value.innerHTML = excelData[0][0]
return return
} }
const clipboardData = pasteCustomClipboardString(text)
if (typeof clipboardData === 'object') return
emit('updateValue', text) emit('updateValue', text)
document.execCommand('insertText', false, text) document.execCommand('insertText', false, text)
}) })

View File

@ -61,7 +61,7 @@
contenteditable="plaintext-only" contenteditable="plaintext-only"
:value="cell.text" :value="cell.text"
@updateValue="value => handleInput(value, rowIndex, colIndex)" @updateValue="value => handleInput(value, rowIndex, colIndex)"
@updateExlc="exlc => handleExlcInput(exlc, rowIndex, colIndex)" @insertExcelData="value => insertExcelData(value, rowIndex, colIndex)"
/> />
<div v-else class="cell-text" v-html="formatText(cell.text)" /> <div v-else class="cell-text" v-html="formatText(cell.text)" />
</td> </td>
@ -510,12 +510,18 @@ export default defineComponent({
emit('change', tableCells.value) emit('change', tableCells.value)
}, 300, { trailing: true }) }, 300, { trailing: true })
// exlc // Excel
const handleExlcInput = (exlc:string[][], rowIndex:number, colIndex:number) => { const insertExcelData = (data: string[][], rowIndex: number, colIndex: number) => {
for (let i = 0; i < exlc.length; i++) { let maxRow = data.length
for (let j = 0; j < exlc[i].length; j++) { let maxCol = data[0].length
if (rowIndex + maxRow > tableCells.value.length) maxRow = tableCells.value.length - rowIndex
if (colIndex + maxCol > tableCells.value[0].length) maxCol = tableCells.value[0].length - colIndex
for (let i = 0; i < maxRow; i++) {
for (let j = 0; j < maxCol; j++) {
if (tableCells.value[rowIndex + i][colIndex + j]) { if (tableCells.value[rowIndex + i][colIndex + j]) {
tableCells.value[rowIndex + i][colIndex + j].text = exlc[i][j] tableCells.value[rowIndex + i][colIndex + j].text = data[i][j]
} }
} }
} }
@ -642,7 +648,7 @@ export default defineComponent({
handleMousedownColHandler, handleMousedownColHandler,
contextmenus, contextmenus,
handleInput, handleInput,
handleExlcInput, insertExcelData,
subThemeColor, subThemeColor,
formatText, formatText,
} }

12572
yarn.lock

File diff suppressed because it is too large Load Diff