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
node_modules
/dist
*.lock
# local env files
.env.local

View File

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

View File

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

View File

@ -61,7 +61,7 @@
contenteditable="plaintext-only"
:value="cell.text"
@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)" />
</td>
@ -510,12 +510,18 @@ export default defineComponent({
emit('change', tableCells.value)
}, 300, { trailing: true })
// exlc
const handleExlcInput = (exlc:string[][], rowIndex:number, colIndex:number) => {
for (let i = 0; i < exlc.length; i++) {
for (let j = 0; j < exlc[i].length; j++) {
// Excel
const insertExcelData = (data: string[][], rowIndex: number, colIndex: number) => {
let maxRow = data.length
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]) {
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,
contextmenus,
handleInput,
handleExlcInput,
insertExcelData,
subThemeColor,
formatText,
}

12572
yarn.lock

File diff suppressed because it is too large Load Diff