Ellia.Duan 发表于 2024-10-28 18:02:49

报表插件(ReportSheet)实现预览时设置背景色

本帖最后由 Ellia.Duan 于 2024-10-29 12:21 编辑

ReportSheet可以在模板中为单元格设置背景色,在预览时,字段进行扩展,会为整个字段设置同样的背景色,如下图所示,右侧是模板,左侧是预览数据


但是有一些场景下,需要在数据填报时,对部分数据进行背景色标识,如下图所示,为同一个字段,不同的数据设置背景色。

为此,我们可以通过设置条件格式,或者自定义单元格来实现。
关于条件格式,可以参考这个文章:https://demo.grapecity.com.cn/sp ... ng/condition-format
下面重点介绍下,如何用自定义单元格来实现。
一、创建数据源
let data = [
                {id: 1, name: '张三', age: 27, sex: 0},
                {id: 2, name: "李四", age: 31, sex: 1},
                {id: 3, name: "小王", age: 22, sex: 1},
                {id: 4, name: "小韩", age: 45, sex: 0},
                {id: 5, name: "小明", age: 25, sex: 0},
            ];
const ordersTable = spread.dataManager().addTable('student',
                {
                  autoSync: true,
                  remote: {
                        read: function () {
                            return Promise.resolve(data);
                        },
                        create: function () {
                            return Promise.resolve(data);
                        },
                        update: function (data) {
                            return Promise.resolve(data);
                        },
                        delete: function () {
                            return Promise.resolve(data);
                        },
                  }
                }
            );
二、定义报表基础数据
const reportSheet = spread.addSheetTab(0, 'report', GC.Spread.Sheets.SheetType.reportSheet);

            ordersTable.fetch().then(() => {
                spread.suspendPaint();
                const templateSheet = reportSheet.getTemplate();
                const columns = ['id', 'name', 'age', 'sex'];
                columns.forEach((columnName, i) => {
                  templateSheet.setValue(0, i, columnName);
                  templateSheet.setTemplateCell(1, i, {
                        type: 'List',
                        binding: `student[${columnName}]`,
                  });
                });
                templateSheet.setCellType(1, 1, new RichTextCellType())
                templateSheet.getRange(0, 0, 2, 4).hAlign(GC.Spread.Sheets.HorizontalAlign.center);
                templateSheet.getRange(0, 0, 2, 4).borderLeft(new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thin));
                templateSheet.getRange(0, 0, 2, 4).borderRight(new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thin));
                templateSheet.getRange(0, 0, 2, 4).borderTop(new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thin));
                templateSheet.getRange(0, 0, 2, 4).borderBottom(new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thin));
                templateSheet.getRange(0, 0, 1, 4).backColor('pink');

                spread.resumePaint();
                reportSheet.refresh()
            });
通过上述代码,创建了模板,填充了字段,并设置了样式。
结果如下:

三、定义右键菜单
接下来 ,我们可以添加一个右键菜单,使其选择颜色。
结果如下图所示:

接下来,我们分三个步骤来实现这个效果。
第一步:定义一级菜单以及二级菜单,将其添加到右键菜单。相关代码如下:
var menuItem = {
                commandName: "selectWithBg",
                text: "选择颜色",
                iconClass: "separator",
                visibleContext: "ReportSheetActive",
                subMenu: [
                  {
                        name: "selectColorPicker",
                        command: "selectWithBg",
                  }
                ],

            };
   let config = GC.Spread.Sheets.Designer.DefaultConfig;
            config.contextMenu.push('setBackColor')
            config.commandMap = {
                'setBackColor': menuItem
            };
            var designer = new GC.Spread.Sheets.Designer.Designer(document.getElementById("designerHost"), config);


在上述代码中,通过config.contextMenu.push('setBackColor')来实现添加菜单的目的。

第二步:设置二级菜单dom结构。我们观察上图,二级菜单似乎与其他菜单长得不一样,在这里我们用自定义菜单的方式进行实现。

关于自定义菜单,可以查看这篇学习指南:
https://demo.grapecity.com.cn/sp ... om-menu-view/purejs

我们继续,相关代码如下:


      function CustomMenuView() {
      }

      CustomMenuView.prototype = new GC.Spread.Sheets.ContextMenu.MenuView();
      CustomMenuView.prototype.createMenuItemElement = function (menuItemData) {
            var self = this;
            if (menuItemData.name === "selectColorPicker") {
                var containers = GC.Spread.Sheets.ContextMenu.MenuView.prototype.createMenuItemElement.call(self, menuItemData);
                var supMenuItemContainer = containers;
                while (supMenuItemContainer.firstChild) {
                  supMenuItemContainer.removeChild(supMenuItemContainer.firstChild);
                }
                var colorPicker = createColorpicker();
                supMenuItemContainer.appendChild(colorPicker);

                return supMenuItemContainer;
            } else {
                return GC.Spread.Sheets.ContextMenu.MenuView.prototype.createMenuItemElement.call(self, menuItemData);
            }
      };
      CustomMenuView.prototype.getCommandOptions = function (menuItemData, host, event) {
            if (menuItemData && menuItemData.name === "selectColorPicker") {
                var ele = event.target || event.srcElement;
                return ele.style.backgroundColor;
            }
      };


      // 定义子菜单
      var colors = ['#1abc9c', '#2ecc71', '#3498db', '#9b59b6', '#34495e',
            '#f1c40f', '#e67e22', '#e74c3c'];

      function createColorpicker() {
            var colorPicker = document.createElement('div');
            colorPicker.className = 'colorPickerContent';
            for (var j = 0; j < 8; j++) {
                var colorDom = document.createElement("div");
                colorDom.className = 'colorDom';
                colorDom.style['backgroundColor'] = colors;
                colorPicker.appendChild(colorDom);
            }
            return colorPicker;
      }
在上述代码中,我们获取到当前选中的区域,并遍历单元格,获取其richText值,执行editCell命令。
最后,我们执行下下面这行代码
spread.contextMenu.menuView = new CustomMenuView();
四、定义自定义单元格
执行完上述代码后,发现,设置颜色设置不上去,因为ReportSheet 预览模式下,不支持背景色的修改。这时候我们需要设置自定义单元格。

   function RichTextCellType() {
            this.typeName = "RichTextCellType"
      }

      RichTextCellType.prototype = new GC.Spread.Sheets.CellTypes.Text();
      RichTextCellType.prototype.paint = function (ctx, value, x, y, w, h, style, context) {
            if (value && value.backColor) {
                style.backColor = value.backColor;
            }
            GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, );
      };

在上述代码中,我们重写了paint方法,将paint中style属性进行了修改。
接下来为B2单元格(name字段)设置cellType
templateSheet.setCellType(1, 1, new RichTextCellType())


通过上述代码,我们就简单实现了报表在预览时同一个字段设置不同背景色的需求。

上述代码较复杂,建议还是通过条件格式来完成此需求。
我们来看下最后的效果:


demo:
页: [1]
查看完整版本: 报表插件(ReportSheet)实现预览时设置背景色