rapid-spreadjs 1.0.120 → 1.0.122

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.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++; // 跳过 \n
719
+ i++;
723
720
  }
724
721
  currentRow.push(currentCell);
725
- result.push(currentRow);
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
- result.push(currentRow);
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];
@@ -798,12 +803,14 @@ const BusinessUtils = {
798
803
  * @param sheet 工作表实例
799
804
  * @param testObjectAttrs 检测对象属性配置集合
800
805
  * @param addRowIndex 添加检测对象属性区域的起始行索引,默认为:0
806
+ * @param deleteRowsCount 删除的行数,默认为:0
801
807
  * @param isVertical 是否为纵表,默认为:true
802
808
  * @param contentColStartIndex 表格内容列起始索引,默认为:1
803
809
  * @param contentTotalColCount 表格内容列总数,默认为:77
804
810
  * @param addRowHeight 添加的表格行高,默认为:24(单位为像素)
811
+ * @returns 返回生成的检测对象属性行数
805
812
  */
806
- createTestObjectAttrsCells: (gc, sheet, testObjectAttrs, addRowIndex = 0, isVertical = true, contentColStartIndex = 1, contentTotalColCount = 77, addRowHeight = 24) => {
813
+ createTestObjectAttrsCells: (gc, sheet, testObjectAttrs, addRowIndex = 0, deleteRowsCount = 0, isVertical = true, contentColStartIndex = 1, contentTotalColCount = 77, addRowHeight = 24) => {
807
814
  if (!testObjectAttrs || testObjectAttrs.length === 0) {
808
815
  return;
809
816
  }
@@ -817,13 +824,15 @@ const BusinessUtils = {
817
824
  const testObjectAttrsChunk = chunkJson(testObjectAttrs, rowTestObjectCount);
818
825
  // 暂停绘制
819
826
  sheet.suspendPaint();
820
- // // 设置工作表行数为0
821
- // sheet.setRowCount(0);
822
827
  // 获取当前Sheet的行数
823
828
  const rowCount = sheet.getRowCount();
824
- // 如果满足如下条件,则将末尾的行全部删除
825
- if (addRowIndex > 0 && addRowIndex < rowCount) {
826
- sheet.deleteRows(addRowIndex, rowCount - addRowIndex);
829
+ // 如果添加检测对象属性区域的起始行索引超过了工作表的行数,则设置addRowIndex为工作表的行数
830
+ if (addRowIndex > rowCount - 1) {
831
+ addRowIndex = rowCount;
832
+ }
833
+ // 删除行
834
+ if (deleteRowsCount > 0) {
835
+ sheet.deleteRows(addRowIndex, deleteRowsCount);
827
836
  }
828
837
  /**
829
838
  * 设置单元格字体和大小
@@ -837,7 +846,7 @@ const BusinessUtils = {
837
846
  for (let i = 0; i < testObjectAttrsChunk.length; i++) {
838
847
  const rowAttrArr = testObjectAttrsChunk[i];
839
848
  // 获取总行数
840
- const totalRowCount = sheet.getRowCount();
849
+ const totalRowCount = addRowIndex + i; //sheet.getRowCount();
841
850
  // 添加一行
842
851
  sheet.addRows(totalRowCount, 1);
843
852
  // 设置添加这一行的行高
@@ -887,6 +896,7 @@ const BusinessUtils = {
887
896
  }
888
897
  // 恢复绘制
889
898
  sheet.resumePaint();
899
+ return testObjectAttrsChunk.length;
890
900
  },
891
901
  /**
892
902
  * 获取检测对象属性值集合