rapid-spreadjs 1.0.120 → 1.0.121
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +39 -34
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.cjs.min.js +1 -1
- package/dist/index.cjs.min.js.map +1 -1
- package/dist/index.esm.js +39 -34
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -688,57 +688,81 @@ const SheetUtils = {
|
|
|
688
688
|
return;
|
|
689
689
|
}
|
|
690
690
|
/**
|
|
691
|
-
* 解析从Excel复制的TSV
|
|
691
|
+
* 解析从Excel复制的TSV格式数据,智能处理合并单元格导致的空列
|
|
692
692
|
* @param data 剪贴板中的原始TSV数据
|
|
693
|
-
* @returns
|
|
693
|
+
* @returns 二维数组,代表行和列,已压缩合并单元格
|
|
694
694
|
*/
|
|
695
695
|
function parseExcelData(data) {
|
|
696
696
|
const result = [];
|
|
697
697
|
let currentRow = [];
|
|
698
698
|
let currentCell = '';
|
|
699
|
-
let insideQuotes = false;
|
|
699
|
+
let insideQuotes = false;
|
|
700
700
|
for (let i = 0; i < data.length; i++) {
|
|
701
701
|
const char = data[i];
|
|
702
702
|
if (char === '"') {
|
|
703
|
-
// 遇到引号,切换状态
|
|
704
703
|
if (insideQuotes && data[i + 1] === '"') {
|
|
705
|
-
// 处理转义的双引号 ("")
|
|
706
704
|
currentCell += '"';
|
|
707
|
-
i++;
|
|
705
|
+
i++;
|
|
708
706
|
}
|
|
709
707
|
else {
|
|
710
708
|
insideQuotes = !insideQuotes;
|
|
711
709
|
}
|
|
712
710
|
}
|
|
713
711
|
else if (char === '\t' && !insideQuotes) {
|
|
714
|
-
//
|
|
712
|
+
// 遇到制表符,结束当前单元格
|
|
715
713
|
currentRow.push(currentCell);
|
|
716
714
|
currentCell = '';
|
|
717
715
|
}
|
|
718
716
|
else if ((char === '\n' || char === '\r') && !insideQuotes) {
|
|
719
|
-
//
|
|
720
|
-
// 处理可能是 \r\n 的情况
|
|
717
|
+
// 遇到换行符,结束当前行
|
|
721
718
|
if (char === '\r' && data[i + 1] === '\n') {
|
|
722
|
-
i++;
|
|
719
|
+
i++;
|
|
723
720
|
}
|
|
724
721
|
currentRow.push(currentCell);
|
|
725
|
-
|
|
722
|
+
// 关键改进:压缩当前行,合并连续的空单元格
|
|
723
|
+
const compressedRow = compressRow(currentRow);
|
|
724
|
+
if (compressedRow.length > 0) {
|
|
725
|
+
result.push(compressedRow);
|
|
726
|
+
}
|
|
726
727
|
currentRow = [];
|
|
727
728
|
currentCell = '';
|
|
728
729
|
}
|
|
729
730
|
else {
|
|
730
|
-
// 普通字符,添加到当前单元格
|
|
731
731
|
currentCell += char;
|
|
732
732
|
}
|
|
733
733
|
}
|
|
734
|
-
//
|
|
734
|
+
// 处理最后一行
|
|
735
735
|
if (currentCell !== '' || currentRow.length > 0) {
|
|
736
736
|
currentRow.push(currentCell);
|
|
737
|
-
|
|
737
|
+
const compressedRow = compressRow(currentRow);
|
|
738
|
+
if (compressedRow.length > 0) {
|
|
739
|
+
result.push(compressedRow);
|
|
740
|
+
}
|
|
738
741
|
}
|
|
739
|
-
// 过滤掉可能存在的空行(例如复制内容末尾的空白行)
|
|
740
742
|
return result.filter((row) => row.some((cell) => cell.trim() !== ''));
|
|
741
743
|
}
|
|
744
|
+
/**
|
|
745
|
+
* 压缩行数据:将连续的空单元格合并,只保留有内容的单元格
|
|
746
|
+
* 例如:['','','测试'] 变为 ['测试']
|
|
747
|
+
* ['A','','B','','C'] 变为 ['A','B','C']
|
|
748
|
+
*/
|
|
749
|
+
function compressRow(row) {
|
|
750
|
+
const compressed = [];
|
|
751
|
+
let emptyCount = 0;
|
|
752
|
+
for (let i = 0; i < row.length; i++) {
|
|
753
|
+
const cell = row[i].trim();
|
|
754
|
+
if (cell === '') {
|
|
755
|
+
emptyCount++;
|
|
756
|
+
}
|
|
757
|
+
else {
|
|
758
|
+
// 如果之前有空单元格,且当前单元格有内容,且这不是行首
|
|
759
|
+
if (emptyCount > 0 && compressed.length > 0) ;
|
|
760
|
+
compressed.push(cell);
|
|
761
|
+
emptyCount = 0;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
return compressed;
|
|
765
|
+
}
|
|
742
766
|
const allCells = SheetUtils.getSheetSelectCellObjs(sheet);
|
|
743
767
|
const allCellsGroup = groupByJson(allCells, 'row');
|
|
744
768
|
const allCellsEw = [];
|
|
@@ -749,25 +773,6 @@ const SheetUtils = {
|
|
|
749
773
|
const clipboardText = yield navigator.clipboard.readText();
|
|
750
774
|
// 得到剪贴板中的二维数组值
|
|
751
775
|
const clipboardData = parseExcelData(clipboardText);
|
|
752
|
-
// 验证剪贴板的二维数组内容和框选的单元格二维数组是否一致
|
|
753
|
-
let isRight = true;
|
|
754
|
-
if (allCellsEw.length != clipboardData.length) {
|
|
755
|
-
isRight = false;
|
|
756
|
-
}
|
|
757
|
-
else {
|
|
758
|
-
for (let i = 0; i < allCellsEw.length; i++) {
|
|
759
|
-
const row = allCellsEw[i];
|
|
760
|
-
const clipboardRow = clipboardData[i];
|
|
761
|
-
if (row.length != clipboardRow.length) {
|
|
762
|
-
isRight = false;
|
|
763
|
-
break;
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
if (!isRight && callFn != null && callFn != undefined && typeof callFn == 'function') {
|
|
768
|
-
callFn(false, '复制的内容区域和框选的表格区域不一致!');
|
|
769
|
-
return;
|
|
770
|
-
}
|
|
771
776
|
sheet.suspendPaint();
|
|
772
777
|
for (let i = 0; i < allCellsEw.length; i++) {
|
|
773
778
|
const row = allCellsEw[i];
|