首页 > 其他分享 >SpreadJS 个人学习及项目遇到的一些问题的总结

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

时间:2024-08-09 17:06:47浏览次数:13  
标签:总结 SpreadJS 遇到 Spread spread GC var const

最近公司有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 = spread
		detectionResult.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.response
                var reader = new FileReader()
                reader.onload = function (e) {
                    var fontrrayBuffer = reader.result
                    var fonts = GC.Spread.Sheets.PDF.PDFFontsManager.getFont(name) || {}
                    fonts[type] = fontrrayBuffer
                    GC.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 = -1
		for (var i = rowCount - 1; i >= 0; i--) {
			var isBlank = true
			for (var j = 0; j < spread.getColumnCount(); j++) {
				if (spread.getCell(j).value !== null && spread.getCell(j).value !== '') {
					isBlank = false
					break
				}
			}
			if (!isBlank) {
				lastNonBlankRowIndex = i
				break
			}
		}
		// 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的,不然导出文件 图片出不来



标签:总结,SpreadJS,遇到,Spread,spread,GC,var,const
From: https://www.cnblogs.com/aowu666/p/18279856

相关文章

  • C# & Unity 面向对象补全计划 七大原则 之 合成/聚合复用原则( CARP)难度:☆☆☆☆ 总结:
    本文仅作学习笔记与交流,不作任何商业用途,作者能力有限,如有不足还请斧正本系列作为七大原则和设计模式的进阶知识,看不懂没关系请看专栏:http://t.csdnimg.cn/mIitr,查漏补缺1.合成/聚合复用原则(CARP)        合成/聚合复用原则就是在一个新的对象里面使用一些已有的......
  • Hadoop学习总结
    在Hadoop学习的过程中,我进入了更具挑战性的阶段——编写和优化MapReduce任务。MapReduce是一种处理大规模数据集的编程模型,它将复杂的数据处理任务分解为两个主要阶段:Map(映射)和Reduce(归约)。通过这一过程,我不仅能解决实际的数据处理问题,还能在分布式环境中高效地执行计算任务。编......
  • 8.9第四周周五学习总结
    1最小生成树(讲课)【金山文档|WPS云文档】最小生成树https://kdocs.cn/l/cnDfoEEJS694prim模板(不常用)#include<bits/stdc++.h>usingnamespacestd;//#defineintlonglongconstintN=1100;constintmod=998244353;vector<int>v[N];#defineINF0x3f3f3f3f......
  • JavaScript -- 总结 10 (小白)
    MouseEvent属性<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document<......
  • 【总结】注册码泄露原理以及例题
    引言题目给了小明的机器码:1653643685031597用户user_id:xiaoming可以看到题目采用了SIMD指令集该指令格式在CTF和攻防对抗中经常出现,可以提高执行效率的同时也可以增加逆向的难度。对于此类指令和题目,我们分析的方法是:遇到查意思,查的多了就跟看正常代码一样,采用动态分析。机......
  • Flux 生态更新总结
    :FLUXTinyVAE训练脚本FluxAIGridComparisons::FLUX生成的发型、服装、国籍、年龄等各种图像对比集合ComfyUI:适配 xlabsFluxcontrolnetcomfyui-replicateInstantX/FLUX.1-dev-Controlnet-Canny-alpha:又一个CannyControlNet模型daniel5984/flux_TrainingFLUX.1-DEV-Ca......
  • 深度学习每周学习总结N6:使用Word2vec实现文本分类
    ......
  • 多线程学习总结
    Java多线程学习总结本章目标理解线程的基本概念理解线程与进程的区别熟悉线程的实现方式了解线程的管理熟悉线程的生命周期掌握线程同步掌握线程池了解线程通信掌握线程定时器什么是进程进程就是正在运行的程序,它是系统进行资源分配和调度的基本单位,各个进程之间......
  • 通过删除按钮从列表框中删除时,减去数字值时遇到一些问题
    我尝试了不同的组合来尝试在点餐时获取要减去的值,并成功地将项目从列表框中删除,但尚未从“总价值”中删除项目值。这是我多次尝试获取要减去的值时遇到的问题。有谁能够获得从列表框中删除后从总值中减去的值吗?importtimeimporttkinterastkfromPILimportImage,ImageT......
  • 我在制作 python 语音应用程序时遇到错误
    我编写了一个语音聊天应用程序代码,但是当我们运行此代码并加入语音频道时,我收到照片中的错误错误1错误2这是我的代码;客户端代码:importtkinterastkfromtkinterimportmessageboximportpyaudioimportsocketimportthreadingimporttimeHOST=......