【用JS自制表格软件玩数据】4. 行列计数器的实现

2023-11-07

当写完本系列后,我会把源代码分享出来给大家。本课程也会持续更新与矫正。欢迎留言指正!

前面已经设计了一个底层渲染类,现在准备在这个底层类的基础上,构建一个渲染单元格的模块。

列计数器

通常在 Excel 表格中,我们会看到横向的标尺使用了:A,B,C,D之类的字母作为标记。
使用了:A,B,C,D之类的字母作为标记

原理

字母的显示,一般都是使用了ASCII码进行表示的,所以,大写字母的 A-Z 是从 65 开始的,到 90 结束。

二进制 十进制 十六进制 缩写/字符 解释
00000000 0 00 NUL(null) 空字符
00000001 1 01 SOH(start of headling) 标题开始
00000010 2 02 STX (start of text) 正文开始
00000011 3 03 ETX (end of text) 正文结束
00000100 4 04 EOT (end of transmission) 传输结束
00000101 5 05 ENQ (enquiry) 请求
00000110 6 06 ACK (acknowledge) 收到通知
00000111 7 07 BEL (bell) 响铃
00001000 8 08 BS (backspace) 退格
00001001 9 09 HT (horizontal tab) 水平制表符
00001010 10 0A LF (NL line feed, new line) 换行键
00001011 11 0B VT (vertical tab) 垂直制表符
00001100 12 0C FF (NP form feed, new page) 换页键
00001101 13 0D CR (carriage return) 回车键
00001110 14 0E SO (shift out) 不用切换
00001111 15 0F SI (shift in) 启用切换
00010000 16 10 DLE (data link escape) 数据链路转义
00010001 17 11 DC1 (device control 1) 设备控制1
00010010 18 12 DC2 (device control 2) 设备控制2
00010011 19 13 DC3 (device control 3) 设备控制3
00010100 20 14 DC4 (device control 4) 设备控制4
00010101 21 15 NAK (negative acknowledge) 拒绝接收
00010110 22 16 SYN (synchronous idle) 同步空闲
00010111 23 17 ETB (end of trans. block) 传输块结束
00011000 24 18 CAN (cancel) 取消
00011001 25 19 EM (end of medium) 介质中断
00011010 26 1A SUB (substitute) 替补
00011011 27 1B ESC (escape) 溢出
00011100 28 1C FS (file separator) 文件分割符
00011101 29 1D GS (group separator) 分组符
00011110 30 1E RS (record separator) 记录分离符
00011111 31 1F US (unit separator) 单元分隔符
00100000 32 20 (space) 空格
00100001 33 21 !  
00100010 34 22 "  
00100011 35 23 #  
00100100 36 24 $  
00100101 37 25 %  
00100110 38 26 &  
00100111 39 27 '  
00101000 40 28 (  
00101001 41 29 )  
00101010 42 2A *  
00101011 43 2B +  
00101100 44 2C ,  
00101101 45 2D -  
00101110 46 2E .  
00101111 47 2F /  
00110000 48 30 0  
00110001 49 31 1  
00110010 50 32 2  
00110011 51 33 3  
00110100 52 34 4  
00110101 53 35 5  
00110110 54 36 6  
00110111 55 37 7  
00111000 56 38 8  
00111001 57 39 9  
00111010 58 3A :  
00111011 59 3B ;  
00111100 60 3C <  
00111101 61 3D =  
00111110 62 3E >  
00111111 63 3F ?  
01000000 64 40 @  
01000001 65 41 A  
01000010 66 42 B  
01000011 67 43 C  
01000100 68 44 D  
01000101 69 45 E  
01000110 70 46 F  
01000111 71 47 G  
01001000 72 48 H  
01001001 73 49 I  
01001010 74 4A J  
01001011 75 4B K  
01001100 76 4C L  
01001101 77 4D M  
01001110 78 4E N  
01001111 79 4F O  
01010000 80 50 P  
01010001 81 51 Q  
01010010 82 52 R  
01010011 83 53 S  
01010100 84 54 T  
01010101 85 55 U  
01010110 86 56 V  
01010111 87 57 W  
01011000 88 58 X  
01011001 89 59 Y  
01011010 90 5A Z  
01011011 91 5B [  
01011100 92 5C \  
01011101 93 5D ]  
01011110 94 5E ^  
01011111 95 5F _  
01100000 96 60 `  
01100001 97 61 a  
01100010 98 62 b  
01100011 99 63 c  
01100100 100 64 d  
01100101 101 65 e  
01100110 102 66 f  
01100111 103 67 g  
01101000 104 68 h  
01101001 105 69 i  
01101010 106 6A j  
01101011 107 6B k  
01101100 108 6C l  
01101101 109 6D m  
01101110 110 6E n  
01101111 111 6F o  
01110000 112 70 p  
01110001 113 71 q  
01110010 114 72 r  
01110011 115 73 s  
01110100 116 74 t  
01110101 117 75 u  
01110110 118 76 v  
01110111 119 77 w  
01111000 120 78 x  
01111001 121 79 y  
01111010 122 7A z  
01111011 123 7B {  
01111100 124 7C |  
01111101 125 7D }  
01111110 126 7E ~  
01111111 127 7F DEL (delete) 删除

这个就要做一个表格坐标计数器来做统计。

步进器

首先设计一个步进器:

/**
* @property {Function} excel_Row_Increase 行移动定位
* @param {String} chr 例如:A1
* @param {String} num 例如:步进
* @returns {Array} 返回字符串数组,["A","1"]
*/
excel_Row_Increase(chr,num){
	this.caculate = function(chr,num){
		var carry = num; // 进位标志
		let temp = chr.split("");
		var count = temp.length-1;
		while(!(count < 0)) {
			let code = this.charmap[temp[count]] + carry;
			carry = 0;

			if (code > 64 && code < 91){
				temp[count] = String.fromCharCode(code);
			}

			while(code < 65){
				carry--;
				code = code + 26;
				if(code > 64){
					temp[count] = String.fromCharCode(code);
					break;
				}
			}

			while(code > 90){
				carry++;
				code = code - 26;
				if(code < 91){
					temp[count] = String.fromCharCode(code);
					break;
				}
			}
			count--;
		}
		var chr = temp.join("");
		if(chr == "A" && carry < 0){
			return {
				"carry":0,
				"char": chr
			}
		}else{
			return {
				"carry":carry,
				"char":chr
			}
		}
	}

	var result = this.caculate(chr,num);
	var ttt;
	while(result["carry"]!=0){
		ttt = this.caculate("A",--result["carry"]);
		result["char"] = ttt["char"]+result["char"];
		result["carry"] = ttt["carry"];
	}
	return result["char"];

}

字符的运算表

接着,使用步进器创建了一个字符的运算表,这样它就可以快速运算了。

/**
	* @property {Function} setcaculatemap 创建字母运算表
	* @returns {NaN} 无返回
	*/
	setcaculatemap(){
		var begin = "A";
		var mapsize = this.mapsize;
		this.caculatemap = [""];
		
		while(mapsize){
			this.caculatemap.push(begin);
			var begin = this.excel_Row_Increase(begin,1)
			mapsize--;
		}
	}

源码

直接上全部代码:

/**
 * 字符转编码
 */

class charcode{
	/**
	* 创建字符映射集
	*/
	constructor(){
		this.charmap = {};
		var ord = 65;
		var ordmax = ord+26;
		while(ord < ordmax){
			this.charmap[String.fromCharCode(ord)] = ord;
			ord++;
		}
		ord = 65+32;
		ordmax = ord+26;
		while(ord < ordmax){
			this.charmap[String.fromCharCode(ord)] = ord-32;
			ord++;
		}
		this.caculatemap = [];
		this.mapsize = 20;
		this.setcaculatemap();
		// console.log(this.caculatemap);
		
		this.RowColcountMap = {};
	}

	/**
	* @property {Function} setcaculatemap 创建字母运算表
	* @returns {NaN} 无返回
	*/
	setcaculatemap(){
		var begin = "A";
		var mapsize = this.mapsize;
		this.caculatemap = [""];
		
		while(mapsize){
			this.caculatemap.push(begin);
			var begin = this.excel_Row_Increase(begin,1)
			mapsize--;
		}
	}
	
	/**
	* @property {Function} countelementToindex 计算坐标在单元格的位置
	* @param {String} x 输入编码,表格的横向尺寸
	* @param {Number} y 输入编码,表格的纵向尺寸
	* @param {String} elementIndex 输入编码
	* @returns {Number} 返回数字坐标
	*/
	countelementToindex(x,y,elementIndex){
		var count = this.CharToDecimal(x); // 字符转坐标
		var titlecount = count+y+1; // 标头长度
		// var max = count*(y); // 表格总尺寸
		var ttt = this.getRowCol(elementIndex); // 分离行列
		var currentX = this.caculatemap.indexOf(ttt[0]) // 获取行的坐标

		return count*(ttt[1]-1)+currentX+titlecount-1;
	}

	/**
	* @property {Function} countindexToelement 将当前位置转化为坐标
	* @param {String} x 输入编码,表格的横向尺寸
	* @param {Number} y 输入编码,表格的纵向尺寸
	* @param {Number} index 输入位置
	* @returns {Number} 返回坐标
	*/
	countindexToelement(x,y,index){
		var count = this.CharToDecimal(x); // 字符转坐标,获得横向的宽度
		var titlecount = count+y+1; // 标头总数量
		var max = count*(y); // 表格总尺寸
		
		var A = titlecount; // 获取A的位置
		var ttt = index-A+1; // 获取输入框的总个数
		if(ttt >= count){
			var mod = ttt%count;
			if(mod != 0){
				return this.caculatemap[mod]+(parseInt(ttt/count)+1)
			}else{
				return this.caculatemap[count]+(parseInt(ttt/count))
			}
		}else{
			return this.caculatemap[ttt]+1
		}
	}

	/**
	* @property {Function} CHR 编码转字符
	* @param {Number} ord 输入编码
	* @returns {String} 返回字符编码
	*/
	CHR(ord){
		return String.fromCharCode(ord);
	}

	/**
	* @property {Function} ORD 字符转编码
	* @param {String} chr 输入字符串
	* @returns {Number} 返回字符编码
	*/
	ORD(chr){
		return chr.charCodeAt(0);
	}

	/**
	* @property {Function} CharToDecimal 进制字符转十进制
	* @param {String} chr 输入字符串
	* @returns {Number} 返回十进制编码
	*/
	CharToDecimal(Char){
		var Decimal = this.caculatemap.indexOf(Char);
		while(Decimal < 0){
			this.mapsize = this.mapsize*10;
			this.setcaculatemap();
			Decimal = this.caculatemap.indexOf(Char);
		}
		return Decimal;
	}

	/**
	* @property {Function} DecimalToChar 十进制转字符进制
	* @param {Number} Decimal 输入十进制
	* @returns {String} 返回字符进制
	*/
	DecimalToChar(Decimal){
		var length = this.caculatemap.length-1;
		var balance = Decimal - length;
		if(balance > 0){
			this.mapsize = this.mapsize+balance+1;
			this.setcaculatemap();
		}
		return this.caculatemap[Decimal];
	}

	/**
	* @property {Function} CharAdd 字母相加
	* @param {String} CharA 输入字符
	* @param {String} CharB 输入字符
	* @returns {Number} 返回十进制编码
	*/
	CharAdd(CharA,CharB){ // 字母相加
		return this.CharToDecimal(CharA)+this.CharToDecimal(CharB)
	}
	
	/**
	* @property {Function} CharMinus 字母相减
	* @param {String} CharA 输入字符
	* @param {String} CharB 输入字符
	* @returns {Number} 返回十进制编码
	*/
	CharMinus(CharA,CharB){ // 字母相减
		return this.CharToDecimal(CharA)-this.CharToDecimal(CharB)
	}

	/**
	* @property {Function} getRowCol 从行列串中分离出行与列
	* @param {String} RC 行列串,例如:A1
	* @returns {Array} 返回字符串数组,["A","1"]
	*/
	getRowCol(RC){
		var Row = [];
		var Col = [];

		for(var i in RC){
			this.charmap.hasOwnProperty(RC[i])?Col.push(RC[i]):Row.push(RC[i]);
		}
		return [Col.join(""),Row.join("")]
	}

	/**
	* @property {Function} setRectanglecorner 设置四个坐标角落
	* @param {String} a 坐标,例如:A1
	* @param {String} b 坐标,例如:B2
	* @returns {Array} 返回字符串数组,["A","1"]
	*/
	setRectanglecorner(a,b){
		var RSort = [];
		var CSort = [];
		var aRC = this.getRowCol(a);
		var bRC = this.getRowCol(b);
		var Rdistance = this.CharMinus(bRC[0],aRC[0]);
		if(Rdistance < 0){
			RSort = [bRC[0],aRC[0]];
		}else{
			RSort = [aRC[0],bRC[0]];
		}
		if(bRC[1]-aRC[1]<0){
			CSort = [bRC[1],aRC[1]];
		}else{
			CSort = [aRC[1],bRC[1]];
		}
		
		return [[RSort[0],CSort[0]],[RSort[1],CSort[1]]]
	}

	/**
	* @property {Function} GetRectangle 计算出框选区域
	* @param {String} from 行列串,例如:A1
	* @param {String} to 行列串,例如:B2
	* @returns {Array} 返回字符串数组,["A","1"]
	*/
	GetRectangle(from,to){
		var t = this.setRectanglecorner(from,to);
		var fromRC = t[0];
		var toRC = t[1];

		var distance =
		[
			this.CharMinus(toRC[0],fromRC[0]),
			toRC[1]-fromRC[1]
		]
		// console.log(fromRC);
		// console.log(toRC);
		// console.log(distance);
		var Rowcount = parseInt(fromRC[1])+distance[1]+1;
		var ColList = this.caculatemap.slice(this.CharToDecimal(fromRC[0]),this.CharToDecimal(fromRC[0])+distance[0]+1);
		var length = ColList.length;
		var Rectangle = [];
		for(var i = 0;i<length;i++){
			for(var j = fromRC[1];j<Rowcount;j++){
				Rectangle.push(ColList[i]+j);
			}
		}
		return {
			"Rowlength":Rowcount-parseInt(fromRC[1]),
			"Collength":length,
			"Rectangle":Rectangle
		};
	}

	/**
	* @property {Function} excel_Row_Increase 行移动定位
	* @param {String} chr 例如:A1
	* @param {String} num 例如:步进
	* @returns {Array} 返回字符串数组,["A","1"]
	*/
	excel_Row_Increase(chr,num){
		this.caculate = function(chr,num){
			var carry = num; // 进位标志
			let temp = chr.split("");
			var count = temp.length-1;
			while(!(count < 0)) {
				let code = this.charmap[temp[count]] + carry;
				carry = 0;

				if (code > 64 && code < 91){
					temp[count] = String.fromCharCode(code);
				}

				while(code < 65){
					carry--;
					code = code + 26;
					if(code > 64){
						temp[count] = String.fromCharCode(code);
						break;
					}
				}

				while(code > 90){
					carry++;
					code = code - 26;
					if(code < 91){
						temp[count] = String.fromCharCode(code);
						break;
					}
				}
				count--;
			}
			var chr = temp.join("");
			if(chr == "A" && carry < 0){
				return {
					"carry":0,
					"char": chr
				}
			}else{
				return {
					"carry":carry,
					"char":chr
				}
			}
		}

		var result = this.caculate(chr,num);
		var ttt;
		while(result["carry"]!=0){
			ttt = this.caculate("A",--result["carry"]);
			result["char"] = ttt["char"]+result["char"];
			result["carry"] = ttt["carry"];
		}
		return result["char"];

	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【用JS自制表格软件玩数据】4. 行列计数器的实现 的相关文章

随机推荐

  • C语言libcurl库的使用

    官方参考资料 https curl haxx se libcurl c https curl haxx se libcurl c example html 下面咱用curl的c语言代码库来实现下面命令行 这是获取同样的返回 其中加入了 d
  • C++基础——面向对象的三大特性:封装、继承、多态

    总学习目录 封装 定义 封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念 这样能避免受到外界的干扰和误用 从而确保了安全 数据封装引申出了另一个重要的 OOP 概念 即数据隐藏 数据封装是一种把数据和操作数据的函数捆绑在一起
  • CUBEMX完成初始化

    目录 软件包下载 选择芯片类型 引脚选择 时钟设置 文件生成路径 设置为代码自动更新 打开文件运行 流水灯 软件包下载 选择芯片类型 引脚选择 三个引脚都选择为推挽输出模式 时钟设置 文件生成路径 中文路径下需要手动安装启动文件 设置为代码
  • mmpose关键点(四):优化关键点模型(原理与代码讲解,持续更新)

    在工程中 模型的运行速度与精度是同样重要的 本文中 我会运用不同的方法去优化比较模型的性能 希望能给大家带来一些实用的trick与经验 有关键点检测相关经验的同学应该知道 关键点主流方法分为Heatmap based与Regression
  • openwrt第三方插件库及插件包安装方法及名称对照表

    openwrt第三方插件库及插件包安装方法及名称对照表 把openwrt packages与small仓库重新归类 ssr passwall vssr以及依赖合并small 喜欢追新的可以去下载small package 该仓库每天自动同步
  • 实现isPrime()函数,参数为整数,要有异常处理,如果是质数返回True,否则返回False

    实现isPrime 函数 参数为整数 要有异常处理 如果是质数返回True 否则返回False def isPrime n if n lt 2 return False else for i in range 2 int pow n 0 5
  • (数据结构)循环队列操作——C实现

    队列 特点 1 先进先出 2 对队列的操作可以理解为头删 尾插 在这里我们主要实现循环队列 循环队列的结构设计 typedef struct Que Elemtype data 存储空间 int front int rear SeQueue
  • 操作系统笔记七(Linux文件操作与文件系统)

    1 Linux的文件基本操作 1 1Linux目录 Linux也有一个目录树 如下图 绝对路径 是从盘符开始的路径 形如C windows system32 cmd exe 相对路径 是从当前路径开始的路径 假如当前路径为C windows
  • 前言-如何学习区块链

    最新内容会更新在主站深入浅出区块链社区 原文链接 前言 如何学习区块链 摘要 区块链未来3到5年应该会出现行业井喷式发展 相应所需的人才必定水涨船高 每一个开发人员都不应该错过这样的机会 区块链涉及的技术很多 很多开发人员看了一些资料后 感
  • C语言常见问题(10):Sections of code should not be commented out

    注释掉的代码及时清理掉 让函数的body干净清洁 不要杂草丛生
  • clang: error: no such file or directory:xxx的处理方法

    经常会遇到这个问题 后来看了一下 大概是在编程的适合改变了工程目录结构 在编译的时候无法找到相应的文件结构 说句话白话 编译器是傻的 你小心或者不小心 结果文件的结果和以前不一样了 编译器是不知情的 还按照之前的方式进行文件之间的链接 所以
  • JavaScript面试题看这一篇就够了,简单全面一发入魂(持续更新 step1)

    目录 1 BOM DOM有什么区别 1 DOM 2 BOM 2 JavaScript中代码后加不加分号 有什么区别 3 var与let const有什么区别 4 原始值和引用值有什么区别 5 什么是执行上下文 6 解释一下JavaScrip
  • hive的高级分组

    1 with cube 2的n次方 使用场景 维度字段之间无关系 底层分组实现 可以实现hive多个任意维度的查询 cube a b c 则首先会对 a b c 进行group by 然后依次是 a b a c a b c b c 最后在对
  • 「已解决」 iTunes 由于卸载 Apple Software Upadate 失败的问题。

    已解决 iTunes 由于卸载 Apple Software Upadate 失败的问题 官方给出的解决方案是 相信大家都会卡在第 2 个步骤上面 卸载 Apple Software Update 时发生出错 这里给出几个方案 方案 1 将
  • 广电大数据用户画像及营销推荐策略(四)——Python实现

    本次大数据项目数据及分析均做脱敏化和保密化 主要分享思路体系 全程用Python实现 数据和代码均不提供 如有建议欢迎讨论 4 模型构建 在实际应用中 构造推荐系统时 并不是采用单一的某种推荐方法进行推荐 为了实现较好的推荐效果 大部分都将
  • 读书思考:步步惊心的《技术陷阱》

    技术陷阱 这本书450页 43万字之巨 信息量密密麻麻 采集的资料极其丰富 复习了一遍大停滞 大分流 大平衡 大逆转时代 并展望未来 看完了有很多想法 随手写了下来 希望不是蹭热点 一 时间折半加速 忽略人类起源到中世纪的万年大停滞 175
  • unity 调用 .dll 或 .so时遇到的问题

    1 32位的 dll 无法在64位的unity编辑器下运行 System DllNotFoundException xxx 64位的程序运行32位的dll是会报这种错 2 Failed to load Assets Plugins xxx
  • 个人网站实现微信扫码登录

    个人网站实现微信扫码登录 效果图 外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直接上传 img kzSrNgiv 1685034480658 https img ggball top picGo 动画 gif 开发背景 为什么
  • javascript canvas 模拟mac最小化

    文章是别人写的 不是我自己的 链接忘记了
  • 【用JS自制表格软件玩数据】4. 行列计数器的实现

    渲染单元格 列计数器 原理 步进器 字符的运算表 源码 当写完本系列后 我会把源代码分享出来给大家 本课程也会持续更新与矫正 欢迎留言指正 前面已经设计了一个底层渲染类 现在准备在这个底层类的基础上 构建一个渲染单元格的模块 列计数器 通常