找回密码
 立即注册

QQ登录

只需一步,快速开始

zhouy123456

注册会员

8

主题

26

帖子

76

积分

注册会员

积分
76
最新发帖

[处理中] 自定义单元格

zhouy123456
注册会员   /  发表于:2024-5-7 20:04  /   查看:318  /  回复:9
1金币
本帖最后由 Richard.Huang 于 2024-5-9 11:59 编辑

产品:SpreadJS

自定义的一种单元格可以添加单元格图片,并且保存了,但是重新渲染的时候,单元格的格式变成了普通的单元格,展示的是图片的base64编码,如何在初始化的时候就根据内容将单元格按照自定义单元格渲染展示单元格图片。

image.png530408629.png

9 个回复

倒序浏览
Richard.HuangSpreadJS 开发认证
超级版主   /  发表于:2024-5-8 09:39:10
沙发
您好,您可以参考我们这篇学习指南去将您自定义的单元格类型进行序列化和反序列化:https://demo.grapecity.com.cn/sp ... erialization/purejs
image.png228042906.png
回复 使用道具 举报
zhouy123456
注册会员   /  发表于:2024-5-9 14:44:15
板凳
Richard.Huang 发表于 2024-5-8 09:39
您好,您可以参考我们这篇学习指南去将您自定义的单元格类型进行序列化和反序列化:https://demo.grapecity ...

我有两个问题,第一个是添加了自定义单元格,单元格为渲染单元格图片,但是toFile()的时候保存的只是单元格耳朵base64,还有如果我上传了外部的excel,外部excel添加了单元格,用url渲染的时候,内容是一个函数=DISPIMG("ID_072F0DFBF7AC401380459C9599CE381B",1),如何获取到base64用自定义单元格渲染出来
回复 使用道具 举报
zhouy123456
注册会员   /  发表于:2024-5-9 16:29:09
地板
本帖最后由 zhouy123456 于 2024-5-9 16:32 编辑


export function MutipHyperLinkPictureCellType(items, size, isHorizontal) {
  this.typeName = 'MutipHyperLinkPictureCellType'
  this._size = size || 22
  this._isHorizontal = isHorizontal || false
  this._items = items || []
  this._valueArr = []
  this._itemsTextWidth = []
  this._maxItemTextWidth = 0
  this._sumItemTextWidth = 0
  this._zoomCatah = 1
  this._autofitheight = 0
  this._autofitwidth = 0
  this.hasPictureSet = false
}
MutipHyperLinkPictureCellType.prototype = new spreadNS.CellTypes.Base()


MutipHyperLinkPictureCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
  console.log('paint~~~', x, y, w, h, value, style, options, this.hasPictureSet)
  if (this.hasPictureSet && !value) {
    this._valueArr = []
    const sheet = options.sheet
    const textCellType = new window.GC.Spread.Sheets.CellTypes.Text(
      window.GC.Spread.Sheets.CellTypes.EditorType.textarea
    )
    const startRow = sheet.getActiveRowIndex()
    const startCol = sheet.getActiveColumnIndex()
    sheet.setCellType(startRow, startCol, textCellType)
  }
  // 保存当前绘图上下文的状态
  ctx.save()

  // 清除当前单元格区域的内容(如果需要)
  ctx.clearRect(x, y, w, h)

  if (!value) {
    this.hasPictureSet = false
    this._valueArr = []
  } else {
    this.hasPictureSet = true
    this._valueArr = []
    window.GC.Spread.Sheets.CellTypes.Base.prototype.paint.call(this, ctx, '', x, y, w, h, style, options)
    if (!ctx) {
      return
    }
    const sheet = options.sheet
    const zoomFactor = sheet.zoom()
    const startX = this._getPaintStartX(x, y, w, h, style.hAlign),
      startY = this._getPaintStartY(x, y, w, h, style.vAlign)
    ctx.save()
    ctx.rect(x, y, w, h)
    ctx.clip()

    ctx.font = style.font
    ctx.fillStyle = style.foreColor

    this._zoomCatah = zoomFactor

    const hyperStyle = new window.GC.Spread.Sheets.Style()
    hyperStyle.foreColor = 'blue'
    hyperStyle.font = style.font

    const backgroundImgStyle = new window.GC.Spread.Sheets.Style()
    backgroundImgStyle.backgroundImage = value

    const valueObj = {}
    valueObj.width = w * 0.8
    valueObj.value = value
    this._valueArr.push(valueObj)

    window.GC.Spread.Sheets.CellTypes.Text.prototype.paint.call(
      this,
      ctx,
      '',
      startX,
      startY,
      w,
      h,
      backgroundImgStyle,
      options
    )
  }
  ctx.restore()
}
回复 使用道具 举报
zhouy123456
注册会员   /  发表于:2024-5-9 16:36:06
5#
    async toFile(title) {
      const blob = await this.exportData('excel')//j用toJSON转换为blob
      const file = new File([blob], title + '.xlsx', { type: blob.type })
      return file
    },//将表单转换为file格式的保存到后端   然后初始化渲染的时候拿到file再用fromJSON渲染
回复 使用道具 举报
AlexZ讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2024-5-9 16:51:26
6#
如果是保存为 Excel,像渲染回来正常显示,需要重新设置单元格类型

保存前,需要记录那些图片单元格的位置,例如隐藏的 worksheet 里面

另外,SpreadJS 支持对 Worksheet 进行深隐藏(用户无法通过 UI 显示)
回复 使用道具 举报
zhouy123456
注册会员   /  发表于:2024-5-9 16:53:58
7#
AlexZ 发表于 2024-5-9 16:51
如果是保存为 Excel,像渲染回来正常显示,需要重新设置单元格类型

保存前,需要记录那些图片单元格的位 ...

大神能给个例子吗
回复 使用道具 举报
Richard.HuangSpreadJS 开发认证
超级版主   /  发表于:2024-5-9 17:45:19
8#
您好!如上面同学所说,您在用SpreadJS导出Excel时遇到了问题:您的自定义单元格功能原本是用来渲染图片的,但在导出后图片变成了base64字符串。这是因为Excel本身不支持这种自定义单元格类型,只有SpreadJS支持。您需要在导出的ssjson文件中添加特定属性,以便于SpreadJS在反序列化时能识别并渲染这些自定义单元格。具体步骤请参考我之前提供的链接。

关于图片的处理,SpreadJS只支持IMAGE函数来渲染图片,可以接受base64字符串或URL作为参数。如果您之前使用了IMAGE函数并想用base64代替URL,您可以使用getFormula方法来提取IMAGE中的URL,并利用JavaScript原生方法将其转化成base64字符串。请注意,SpreadJS和Excel都不支持DISPIMG函数。

其次,上面同学所说的深度隐藏调用的API为:
sheet.visible(GC.Spread.Sheets.SheetTabVisible.veryHidden),总的思路就是需要在这个隐藏的sheet上记录您展示的sheet中的自定义单元格类型的位置,然后在下次导入进来后,您再用setCellType去为您的sheet设置对应的单元格类型,附件是一个简单的demo,您可以测试一下

SpreadJSTest.html

5.95 KB, 下载次数: 23

回复 使用道具 举报
zhouy123456
注册会员   /  发表于:2024-5-11 10:15:51
9#
Richard.Huang 发表于 2024-5-9 17:45
您好!如上面同学所说,您在用SpreadJS导出Excel时遇到了问题:您的自定义单元格功能原本是用来渲染图片的 ...

这种存在一个问题,就是如果在sheet1中删除了某个单元格图片,或者新增了行或者列,或者合并了单元格这些,都会导致sheet2中的记录不准确
回复 使用道具 举报
Richard.HuangSpreadJS 开发认证
超级版主   /  发表于:2024-5-13 18:04:50
10#
zhouy123456 发表于 2024-5-11 10:15
这种存在一个问题,就是如果在sheet1中删除了某个单元格图片,或者新增了行或者列,或者合并了单元格这些 ...

是的,因此您需要一些事件监听用户的操作,从而实现对于Sheet2中的数据保证尽量的准确。但是终究这不是一个好的办法,还是期望您能够通过导出成SpreadJS独有的格式文件来进行导入导出的操作。
API参考:https://demo.grapecity.com.cn/sp ... pread.Sheets.Events
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部