找回密码
 立即注册

QQ登录

只需一步,快速开始

Richard.Huang SpreadJS 开发认证
超级版主   /  发表于:2023-10-30 11:47  /   查看:902  /  回复:0
本帖最后由 Richard.Huang 于 2024-1-29 10:38 编辑

背景
数据填报是很多用户使用表格类产品常常会面临的场景,该场景中无非是设计一张模板表,让其他用户按照这个模板表填写相应的信息。
而为了让模板表更加好看清晰,为单元格加上边框就显得很有必要了,漂亮的边框样式,往往可以为用户提供清晰的填报路径,也让阅读者能够明确填报的内容。
但是设计模板时,大家往往会遇到这样的场景,我明明为某个单元格设置了全边框的样式,但总有那么几条边和我设计的样式不一致,我把这个单元格样式通过API取出来查看,却没有异样。难道这是bug?不不不,这往往是因为我们边框样式优先级存在不同,而页面上,往往会显示高优先级的边框样式。

原理解释
边框的属性是在单元格上的,两个相邻单元格共同的边框显示效果是两个单元格优先级高的那个。边框样式无非是颜色、线型、粗细。这三者形成的排列组合有很多很多种,样式杂揉起来我们怎么知道哪些优先哪些次优先呢?我们可以做一个对比实验来探讨。我们通过控制变量法分别对粗细、样式、线型进行分别对照,并且为了排除左右单元格位置差异,我们对每个样式做了两组实验,这样就可以判断单元格位置对样式造成的影响。

如下,我们分别在E列和G列做了如下的颜色对比组、粗细对比组、线型对比组,然后我们将F列删除后两列的单元格就相邻了
image-20231030110121471.png769781493.png
通过删除F列我们可以很容易得出如下结论:黑色>红色、粗>细、实线>虚线
image-20231030110238993.png600592040.png

但是实际生产过程中我们肯定不会单单使用其中一种样式,而是三种样式交叉排列组合来实现,那么颜色、粗细、线型又是谁比较优先呢?
于是我们继续探讨,我们采用**法,我们假设颜色是三个样式最高优先级,那么无论另外两个样式设置成什么样子,都得看颜色的脸色,无论另外两个样式有多不同都不关我的事。于是我将E15单元格设置为黑色细的虚线,G15设置为红色粗的实线,细的虚线两个样式都是低优先级、粗的实线两个样式都是高优先级,那么如果颜色优先级最高,那么我不会管G15的红色边框另外两个样式是什么我都应该显示黑色边框单元格的样式.
image-20231030110954256.png976494750.png
同样的我分别假设粗细优先级最高、线型优先级最高。从而分别作了如上两种对比实现红色粗虚线和和黑色细实线,红色细实线和黑色粗虚线。
接着我们同样删除F列可以很容易得出如下结论:粗细的优先级是三个样式优先级最高的
image-20231030111325783.png50363768.png
那么接下来颜色和线型哪个更高呢?
我们按照上面的假设法,并且排除粗细的干扰分别对颜色、线型做了如下的对比试验:黑色实线和红色虚线、黑色虚线和红色实线
image-20231030111500977.png379588317.png
同样删除F列,我们可以很容易得出以下结论:线型是次优先级
image-20231030112039386.png312244872.png

Excel
image-20231030112644746.png21692198.png

SpreadJS Designer
image-20231030112542057.png625245360.png

样式优先级总结
我们发现Excel和SpreadJS样式优先级大部分是一致的、除了颜色上。我们很清楚的看到我们的在线表格编辑器的颜色优先级上并不是按照黑色>红色来显示、反而是位置起到了决定作用,于是为了详细了解SpreadJS在边框样式上位置对边框的显示,我们专门对SpreadJS做了一个位置的对比实验。

我们将D4设置为红色单元格,上下左右四个方向单元格设置为黑色,除了位置以外、其他都保持一致(颜色是为了区分哪个位置优先显示),然后我们分别将3、5行和C、E列删除,查看边框样式显示
image-20231030113152097.png920601806.png
我们可以很明显的看出,在SpreadJS中,上面单元格的下边框优先于下面单元格的上边框、左边单元格的右边框优先于右边单元格的左边框

image-20231030113309349.png232937316.png

综上所述:在SpreadJS中边框优先级为:粗细>线型>位置

解决方案
既然有这么多优先级,可是我就是记不住咋办呢,而且我就是想让所有单元格边框显示按照我设想的那样显示就行,其他我不关心。这个也很容易,我们将会出现样式冲突的边框在设置之前提前将他周围的单元格与当前单元格相邻的边的样式清空即可(在线表格编辑器的UI也是这样的策略),代码如下:
  1. var rowCol = {
  2.   row: 4,
  3.   col: 7,
  4. };// 当前单元格索引

  5. let span = sheet.getSpan(rowCol.row, rowCol.col);// 判断当前单元格是不是合并单元格
  6. let cell = sheet.getCell(
  7.   rowCol.row,
  8.   rowCol.col,
  9.   GC.Spread.Sheets.SheetArea.viewport
  10. );

  11. span = span ? span : cell;

  12. var borderBottom = new GC.Spread.Sheets.LineBorder(null); // 上
  13. sheet
  14.   .getRange(span.row - 1, span.col, 1, span.colCount)
  15.   .setBorder(borderBottom, { bottom: true });// 将上单元格的下边框的样式设置为空

  16. var borderTop = new GC.Spread.Sheets.LineBorder(null); // 下
  17. sheet
  18.   .getRange(span.row + 1, span.col, 1, span.colCount)
  19.   .setBorder(borderTop, { top: true });// 将下单元格的上边框的样式设置为空

  20. var borderLeft = new GC.Spread.Sheets.LineBorder(null); // 右
  21. sheet
  22.   .getRange(span.row, span.col + span.colCount, span.rowCount, 1)
  23.   .setBorder(borderLeft, { left: true });// 将右单元格的左边框的样式设置为空

  24. var borderRight = new GC.Spread.Sheets.LineBorder(null); // 左
  25. sheet
  26.   .getRange(span.row, span.col - 1, span.rowCount, 1)
  27.   .setBorder(borderRight, { right: true });// 将左单元格的右边框的样式设置为空

  28. // 设置当前单元格的样式
  29. var lineStyle = GC.Spread.Sheets.LineStyle.thin;
  30. var lineBorder = new GC.Spread.Sheets.LineBorder("green", lineStyle);
  31. var sheetArea = GC.Spread.Sheets.SheetArea.viewport;
  32. sheet
  33.   .getRange(span.row, span.col, span.rowCount, span.colCount)
  34.   .setBorder(lineBorder, { all: true }, sheetArea);
复制代码
大家可以将附件的xlsx文件下载到本地进行测试

样式优先级探讨.xlsx

9.94 KB, 下载次数: 16

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部