SpreadJS 个人学习及项目遇到的一些问题的总结

news/2024/11/17 9:41:48/文章来源:https://www.cnblogs.com/aowu666/p/18279856
最近公司有SpreadJS 的部分,刚接触挺迷茫的,因为这个文档有点不清晰,有些属性啥的,看到跟没看一样,他没有那种效果图例说明,属性说的就很简单,看了大半天感觉没看出来啥,等开始做的时候就各种问题,感谢有同事替我们负重前行,趟过了很多的坑,这导致比预期入手好很多,目前只是算简单的上手,所以就简单的分享一些常用的属性及对应功能,说的不对或者不合理的,我可以改正,吐槽也是新手吐槽,仅个人想法,SpreadJS 还是很牛逼的,功能强大,能节省用户对表格的依赖
以下就是他的优缺点,百度的

优点:

  1. 跨平台兼容性:SpreadJS 支持多种浏览器和操作系统,包括桌面和移动设备。

  2. 丰富的功能:SpreadJS 提供了丰富的表格功能,包括单元格编辑、格式设置、公式计算、数据验证等。

  3. 性能:由于它是基于 HTML5 的,因此具有较好的性能和响应速度。

  4. 集成性:SpreadJS 可以与其他前端框架(如 Vue、React 等)集成,方便开发和维护。

  5. API 丰富:SpreadJS 提供了一系列的 API,允许开发者通过编程方式控制表格的各个方面。

缺点:

  1. 成本:SpreadJS 是一个商业产品,需要购买许可证才能使用。对于开源或预算有限的开发项目,这可能是一个障碍。

  2. 社区支持:虽然 SpreadJS 有一个活跃的社区,但与一些流行的开源项目相比,它的社区规模可能较小。

  3. 文档和教程:虽然 SpreadJS 的文档和教程相对完整,但与一些开源项目相比,它们可能不够详细或易于理解。

  4. 定制性:虽然 SpreadJS 提供了丰富的功能和 API,但对于一些特定的定制需求,可能需要额外的开发工作。

  5. 更新频率:SpreadJS 的更新频率可能不如一些开源项目频繁,这可能会影响项目的维护和扩展。

这个是技术文档
https://demo.grapecity.com.cn/spreadjs/help/api/modules/GC.Data

 

我这边只涉及展示部分,表格编辑部分的,目前还没接触过,后期会了再更新,目前是一些常用的情况代码展示

简单的入门开始

视图部分

<gc-spread-sheets style="height: 75vh" @workbookInitialized="initWorkbook"></gc-spread-sheets>

组件引用

	import { message } from 'ant-design-vue'import '@grapecity/spread-sheets/styles/gc.spread.sheets.excel2013white.css'import GC from '@grapecity/spread-sheets'import '@grapecity/spread-sheets-resources-zh'
    GC.Spread.Common.CultureManager.culture('zh-cn')GC.Spread.Sheets.LicenseKey = VITE_SHEETS_LICENSE_KEY
            let _spread = null

 ------------------代码部分--------------

async function initWorkbook(spread) {_spread = spreaddetectionResult.value = []const file = await getFile('https://www.baidu.com')	// 模板地址spread.import(file, () => {// 获取活动工作表的名称列表 这个是多个活动页的时候获取的var sheetNames = []for (var i = 0; i < spread.getSheetCount(); i++) {sheetNames.push(spread.getSheet(i).name())// console.log('---i---------', i)let sheet = spread.getSheet(i)sheet.zoom(1)let printInfo = sheet.printInfo() // 这是是导出pdf的时候正常情况下,使用的设置部分// 这个是底部的页码printInfo.pageHeaderFooter({normal: {footer: {center: '第' + '&P' + '页 共' + '&N' + '页'}}})printInfo.margin({ top: 35, bottom: 75, left: 15, right: 15, header: 10, footer: 20 }) // 这个是外边距,导出的pdf部分,有的页面内容多的情况下,显示不出来// 获取或设置是否在整个控件周围打印分组列边框printInfo.showBorder(false)// 获取或设置打印页面居中的方式printInfo.centering(GC.Spread.Sheets.Print.PrintCentering.horizontal)// 重复表头 打印列表的时候,表头在新的页中是否包含printInfo.repeatRowStart(0)printInfo.repeatRowEnd(1)//是否打印列头/行头  如下图部分printInfo.showColumnHeader(GC.Spread.Sheets.Print.PrintVisibilityType.hide)printInfo.showRowHeader(GC.Spread.Sheets.Print.PrintVisibilityType.hide)

                                    

 

    spread.bind(GC.Spread.Sheets.Events.CellClick, cellClick)  // 这个是点击的时候,获取对应的点位坐标spread.setActiveSheetIndex(0)   // 从第一个开始 设置默认选中

                                     

                           printInfo.fitPagesWide(1)

                                            //  使用场景,当前表格pdf,纵列展示展示不全的解决方案

                                     

 

// 挂起绘制和事件处理
spread.suspendPaint()
spread.suspendEvent()
// 执行大量更新操作
在这里写逻辑 ..............................
// 恢复事件处理/
spread.resumeEvent()
/ 恢复绘制  
spread.resumePaint()

			registerServerFont('st', 'normal', import.meta.env.VITE_PROJECT_BASE + '/simsun.ttf')    // 导出的时候会有乱码,这是解决方案
}) }

  

常用的一些事件方法

// 下面是常用的一些方法封装
// 导出的时候会有乱码,这是解决方案const registerServerFont = (name, type, serverPath) => {var xhr = new XMLHttpRequest()xhr.open('GET', serverPath, true)xhr.responseType = 'blob'xhr.onload = function (e) {console.log(xhr)if (xhr.status == 200) {var blob = xhr.responsevar reader = new FileReader()reader.onload = function (e) {var fontrrayBuffer = reader.resultvar fonts = GC.Spread.Sheets.PDF.PDFFontsManager.getFont(name) || {}fonts[type] = fontrrayBufferGC.Spread.Sheets.PDF.PDFFontsManager.registerFont(name, fonts)// console.log("字体注册完成");GC.Spread.Sheets.PDF.PDFFontsManager.fallbackFont = function () {return fontrrayBuffer}}reader.readAsArrayBuffer(blob)}}xhr.send()}

  点击获取横纵坐标

    const cellClick = (sender, args) => {console.log('click', args.row, args.col, _spread.getActiveSheet().name())}

  单元格的高度自适应

	// 整理 高度自适应const arrangeLIst = (sheetFour) => {const rowCountFour = sheetFour.getRowCount(GC.Spread.Sheets.SheetArea.viewport) // 横for (let index = 0; index < rowCountFour; index++) {adjustRowHeightIfNecessary(sheetFour, index)}}// 根据高度自适应const adjustRowHeightIfNecessary = (sheet, row) => {// 获取当前行的高度var originalHeight = sheet.getRowHeight(row) // 计算自动适应后的行高sheet.autoFitRow(row)var newHeight = sheet.getRowHeight(row) // 如果新高度小于或等于原高度,则将高度重新设回原高度if (newHeight <= originalHeight) {sheet.setRowHeight(row, originalHeight < 25 ? 30 : originalHeight)} else if (newHeight < 25) {sheet.setRowHeight(row, 30)}}使用方法,// 整理 高度自适应arrangeLIst(sheetFour)

  删除多余的行

// 删除多余的行const deletionExcess = (spread) => {const dataR = spread.getUsedRange(GC.Spread.Sheets.UsedRangeType.data)const rowCount = dataR.rowCount // 横// console.log('-----删除多余的行--', rowCount)// 遍历工作表的行,找到最后一个非空白行var lastNonBlankRowIndex = -1for (var i = rowCount - 1; i >= 0; i--) {var isBlank = truefor (var j = 0; j < spread.getColumnCount(); j++) {if (spread.getCell(j).value !== null && spread.getCell(j).value !== '') {isBlank = falsebreak}}if (!isBlank) {lastNonBlankRowIndex = ibreak}}// console.log(spread.getRowCount(), '-----lastNonBlankRowIndex-------', lastNonBlankRowIndex)// 如果找到了最后一个非空白行,删除所有底部的空白行if (lastNonBlankRowIndex !== -1) {for (var i = spread.getRowCount() - 1; i > lastNonBlankRowIndex; i--) {spread.deleteRows(i, 1)}}}使用方法deletionExcess(sheetSix)

添加图片

	const imageSignature = (spreadJsTool, sheet, val, x, y) => {// 签名图片let picture = sheet.pictures.add(spreadJsTool, 'data:image/jpg;base64,' + val)picture.isVisible(false)setTimeout(() => {picture.width((50 / picture.height()) * picture.width())picture.height(48)picture.y(1)// 这个顺序不对会导致报错picture.startRow(x)picture.startColumn(y)picture.isVisible(true)}, 100)}// 图片名称,我用的随机数
const randomString =(length)=> {const array = new Uint32Array(length);window.crypto.getRandomValues(array);return Array.from(array, (dec) => {return dec.toString(36).padStart(2, '0'); // 转换为36进制(包含数字和字母)}).join('');
}console.log(randomString(10)); // 生成长度为10的随机字符串
使用方法imageSignature(randomString(15),sheetSix,item.img,nullAr1,nullAr - nullAr2 > 0 ? nullAr - nullAr2 : 0)

  还有种场景,需要删除当前表格中的文件图片

	// 删除多余的图片//  获取工作表的形状管理器var shapeColl = sheet.shapes//  参照此方式获取图片或形状名称// var pictName = shapeColl.all()[0].name()shapeColl.all().forEach((element) => {if (element.name() != '图片 5') { // 图片5是我想保留的图片shapeColl.remove(element.name())}})

  获取指定单元格内容是否合并 

 sheet.getSpan(row, col)

  导出文件

	const toExcel = async () => {
导出xlsx_spread.export(function (blob) {saveAs(blob, containerTitle.value + '.xlsx')},function (e) {console.log(e)},{fileType: GC.Spread.Sheets.FileType.excel})
导出pdf
		_spread.savePDF(
			function (blob) {saveAs(blob, containerTitle.value + '.pdf')
			},function (e) {console.log(e)},{fileType: GC.Spread.Sheets.FileType.excel})
	}使用方法 @click

  

注: 1.导入文件的时候,文件格式必须是 .xlsx,不然出不来
2.图片必须是base64的,不然导出文件 图片出不来



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/780368.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[设计模式]装饰者模式

抽象构件 public abstract class FastFood {public String desc;public int price;public abstract String getDesc();public abstract int getPrice();}具体构件 米饭 public class Rice extends FastFood {public Rice() {this.desc = "米饭";this.price = 10;}@Ov…

京东面试:说说CMS工作原理?

CMS(Concurrent Mark Sweep)垃圾收集器是以“最短的停顿”著称的垃圾回收器,因此也是 JDK 9 之前使用最广泛的垃圾回收器之一。那么,问题来了,为什么 CMS 能实现最短停顿时间?CMS 垃圾回收器的工作原理又是啥呢?接下来,我们一起来看。 CMS 工作原理 CMS 之所以能实现最…

处理idea中的properties中文乱码问题

如果遇到项目使用了prioperties格式的文件,别人拉取代码乱码,可以进行如下操作 另外的idea中 需要注意的是,请在编辑之前就进行设置

我愿称之为全网最通透的layernorm讲解(往下翻)

在我们平常面试和工程中会用到BN和LN,但或许没有去了解过BN和LN到底在那个维度上进行的正则化(减均值除以标准差)。下面将会采用各种例子来为大家介绍BN层和LN层各个参数以及差别。一、BatchNorm(批标准化):BatchNorm一共有三个函数分别是BatchNorm1d,BatchNorm2d,BatchN…

远程桌面授权服务远程代码执行漏洞(CVE-2024-38077)漏洞预警

影响范围 开启了RDL服务的Windows Server 2000到2025都会受到影响 满足以上条件可以直接RCE 关于RDL 服务名全称,Remote Desktop Licensing,如图:这个就是RDL服务,一般运维应该不会刻意去安装这个的,常用自带默认的远程桌面服务加个白名单就够了:解决办法 1、没装RDL服务…

boot sharing

1.BootRom 计算机系统启动过程的第一步,负责进行硬件初始化和加载Boot Loader到RAM等基本操作 根据不同的启动模式(硬件拨码)去不同的存储设备取bootlaoder(决定指令从哪来 bootrom: rom:掉电不易失存储器,通常为nor flash,可以芯片内执行 boot:存储在上述介质中的一小段…

Flowable自动审核、相邻节点审核、已存在审核人审核

Flowable 监听器的使用 需求背景: 1、发起人发起流程,可以实现发起人自动审核 2、上一节点的审核人,与当前节点审核人相同时,自动审核 3、整个流程实例中,存在已审核的审核人,当前节点自动审核 流程图如下所示:针对于自动审核设置,其实是由前端内置bpnm.xml 去设置的,…

ALLEGRO软件打开提示说没有内存

打开云雾管理器,确认下是不是没有内存,如果是内存没问题就重启下电脑

大数据框架之一——Hadoop学习第四天

1、MapReduce序列化(接着昨天的知识继续学习)序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。 当两个进程在进行远…

div-固定在页面中间,不被其他元素覆盖

最开始设置的子元素D 是text-align:center,子元素C的内容过长的时候,会发现子元素D不在页面正中了 所以需要把子元素D设置成固定中间,把子元素D设置成固定中间后,发现元素B把子元素D给覆盖了一部分, 所以需要在父元素A和元素B之间加一个空的div,给div设置高度后,父元素A…