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.cjs.js CHANGED
@@ -710,57 +710,81 @@ const SheetUtils = {
710
710
  return;
711
711
  }
712
712
  /**
713
- * 解析从Excel复制的TSV格式数据,能处理单元格内换行符
713
+ * 解析从Excel复制的TSV格式数据,智能处理合并单元格导致的空列
714
714
  * @param data 剪贴板中的原始TSV数据
715
- * @returns 二维数组,代表行和列
715
+ * @returns 二维数组,代表行和列,已压缩合并单元格
716
716
  */
717
717
  function parseExcelData(data) {
718
718
  const result = [];
719
719
  let currentRow = [];
720
720
  let currentCell = '';
721
- let insideQuotes = false; // 标记是否正在读取一个被引号包裹的单元格
721
+ let insideQuotes = false;
722
722
  for (let i = 0; i < data.length; i++) {
723
723
  const char = data[i];
724
724
  if (char === '"') {
725
- // 遇到引号,切换状态
726
725
  if (insideQuotes && data[i + 1] === '"') {
727
- // 处理转义的双引号 ("")
728
726
  currentCell += '"';
729
- i++; // 跳过下一个引号
727
+ i++;
730
728
  }
731
729
  else {
732
730
  insideQuotes = !insideQuotes;
733
731
  }
734
732
  }
735
733
  else if (char === '\t' && !insideQuotes) {
736
- // 遇到制表符且不在引号内,结束当前单元格
734
+ // 遇到制表符,结束当前单元格
737
735
  currentRow.push(currentCell);
738
736
  currentCell = '';
739
737
  }
740
738
  else if ((char === '\n' || char === '\r') && !insideQuotes) {
741
- // 遇到换行符且不在引号内,结束当前行
742
- // 处理可能是 \r\n 的情况
739
+ // 遇到换行符,结束当前行
743
740
  if (char === '\r' && data[i + 1] === '\n') {
744
- i++; // 跳过 \n
741
+ i++;
745
742
  }
746
743
  currentRow.push(currentCell);
747
- result.push(currentRow);
744
+ // 关键改进:压缩当前行,合并连续的空单元格
745
+ const compressedRow = compressRow(currentRow);
746
+ if (compressedRow.length > 0) {
747
+ result.push(compressedRow);
748
+ }
748
749
  currentRow = [];
749
750
  currentCell = '';
750
751
  }
751
752
  else {
752
- // 普通字符,添加到当前单元格
753
753
  currentCell += char;
754
754
  }
755
755
  }
756
- // 处理最后一行(如果数据不是以换行符结尾)
756
+ // 处理最后一行
757
757
  if (currentCell !== '' || currentRow.length > 0) {
758
758
  currentRow.push(currentCell);
759
- result.push(currentRow);
759
+ const compressedRow = compressRow(currentRow);
760
+ if (compressedRow.length > 0) {
761
+ result.push(compressedRow);
762
+ }
760
763
  }
761
- // 过滤掉可能存在的空行(例如复制内容末尾的空白行)
762
764
  return result.filter((row) => row.some((cell) => cell.trim() !== ''));
763
765
  }
766
+ /**
767
+ * 压缩行数据:将连续的空单元格合并,只保留有内容的单元格
768
+ * 例如:['','','测试'] 变为 ['测试']
769
+ * ['A','','B','','C'] 变为 ['A','B','C']
770
+ */
771
+ function compressRow(row) {
772
+ const compressed = [];
773
+ let emptyCount = 0;
774
+ for (let i = 0; i < row.length; i++) {
775
+ const cell = row[i].trim();
776
+ if (cell === '') {
777
+ emptyCount++;
778
+ }
779
+ else {
780
+ // 如果之前有空单元格,且当前单元格有内容,且这不是行首
781
+ if (emptyCount > 0 && compressed.length > 0) ;
782
+ compressed.push(cell);
783
+ emptyCount = 0;
784
+ }
785
+ }
786
+ return compressed;
787
+ }
764
788
  const allCells = SheetUtils.getSheetSelectCellObjs(sheet);
765
789
  const allCellsGroup = rapidUtils.groupByJson(allCells, 'row');
766
790
  const allCellsEw = [];
@@ -771,25 +795,6 @@ const SheetUtils = {
771
795
  const clipboardText = yield navigator.clipboard.readText();
772
796
  // 得到剪贴板中的二维数组值
773
797
  const clipboardData = parseExcelData(clipboardText);
774
- // 验证剪贴板的二维数组内容和框选的单元格二维数组是否一致
775
- let isRight = true;
776
- if (allCellsEw.length != clipboardData.length) {
777
- isRight = false;
778
- }
779
- else {
780
- for (let i = 0; i < allCellsEw.length; i++) {
781
- const row = allCellsEw[i];
782
- const clipboardRow = clipboardData[i];
783
- if (row.length != clipboardRow.length) {
784
- isRight = false;
785
- break;
786
- }
787
- }
788
- }
789
- if (!isRight && callFn != null && callFn != undefined && typeof callFn == 'function') {
790
- callFn(false, '复制的内容区域和框选的表格区域不一致!');
791
- return;
792
- }
793
798
  sheet.suspendPaint();
794
799
  for (let i = 0; i < allCellsEw.length; i++) {
795
800
  const row = allCellsEw[i];
@@ -820,12 +825,14 @@ const BusinessUtils = {
820
825
  * @param sheet 工作表实例
821
826
  * @param testObjectAttrs 检测对象属性配置集合
822
827
  * @param addRowIndex 添加检测对象属性区域的起始行索引,默认为:0
828
+ * @param deleteRowsCount 删除的行数,默认为:0
823
829
  * @param isVertical 是否为纵表,默认为:true
824
830
  * @param contentColStartIndex 表格内容列起始索引,默认为:1
825
831
  * @param contentTotalColCount 表格内容列总数,默认为:77
826
832
  * @param addRowHeight 添加的表格行高,默认为:24(单位为像素)
833
+ * @returns 返回生成的检测对象属性行数
827
834
  */
828
- createTestObjectAttrsCells: (gc, sheet, testObjectAttrs, addRowIndex = 0, isVertical = true, contentColStartIndex = 1, contentTotalColCount = 77, addRowHeight = 24) => {
835
+ createTestObjectAttrsCells: (gc, sheet, testObjectAttrs, addRowIndex = 0, deleteRowsCount = 0, isVertical = true, contentColStartIndex = 1, contentTotalColCount = 77, addRowHeight = 24) => {
829
836
  if (!testObjectAttrs || testObjectAttrs.length === 0) {
830
837
  return;
831
838
  }
@@ -839,13 +846,15 @@ const BusinessUtils = {
839
846
  const testObjectAttrsChunk = rapidUtils.chunkJson(testObjectAttrs, rowTestObjectCount);
840
847
  // 暂停绘制
841
848
  sheet.suspendPaint();
842
- // // 设置工作表行数为0
843
- // sheet.setRowCount(0);
844
849
  // 获取当前Sheet的行数
845
850
  const rowCount = sheet.getRowCount();
846
- // 如果满足如下条件,则将末尾的行全部删除
847
- if (addRowIndex > 0 && addRowIndex < rowCount) {
848
- sheet.deleteRows(addRowIndex, rowCount - addRowIndex);
851
+ // 如果添加检测对象属性区域的起始行索引超过了工作表的行数,则设置addRowIndex为工作表的行数
852
+ if (addRowIndex > rowCount - 1) {
853
+ addRowIndex = rowCount;
854
+ }
855
+ // 删除行
856
+ if (deleteRowsCount > 0) {
857
+ sheet.deleteRows(addRowIndex, deleteRowsCount);
849
858
  }
850
859
  /**
851
860
  * 设置单元格字体和大小
@@ -859,7 +868,7 @@ const BusinessUtils = {
859
868
  for (let i = 0; i < testObjectAttrsChunk.length; i++) {
860
869
  const rowAttrArr = testObjectAttrsChunk[i];
861
870
  // 获取总行数
862
- const totalRowCount = sheet.getRowCount();
871
+ const totalRowCount = addRowIndex + i; //sheet.getRowCount();
863
872
  // 添加一行
864
873
  sheet.addRows(totalRowCount, 1);
865
874
  // 设置添加这一行的行高
@@ -909,6 +918,7 @@ const BusinessUtils = {
909
918
  }
910
919
  // 恢复绘制
911
920
  sheet.resumePaint();
921
+ return testObjectAttrsChunk.length;
912
922
  },
913
923
  /**
914
924
  * 获取检测对象属性值集合