关于使用cspreadsheet读写EXCEL表格数据的问题

2024-09-08 12:08

本文主要是介绍关于使用cspreadsheet读写EXCEL表格数据的问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  前几天项目有读写EXCEL表格的需求,我就找了大概有几种,大致分为:COM方法、ODBC方法、OLE方法、纯底层格式分析方法。由于COM方法要求必须安装有OFFICE的EXCEL组件,纯底层格式分析方法又很多功能需要自行去完善,所有最终选择了数据库的方法,用数据库的方法去存取xls格式的数据。网上有一个高手写的CSpreedSheet,看了一下提供的接口,感觉挺好用的。在使用的过程中发现几个问题,做如下探讨:

    1 cspreadsheet的构造问题:

    CSpreadSheet(CString File, CString SheetOrSeparator, bool Backup = true);

    第一个参数不用多说,是xls文件的全路径;

    第二个参数也不用多说,是xls其中某一个表格的名字,不过有趣的是,如果你不确定表格的名称,可以用空字符串代替,它便会默认读取第一个表格;

    第三个参数默认为true,我觉得这个参数是很有问题的。这个参数为true的原始意义是读取表格时额外做个备份,但是如果你的xls表格不是每列每行都全有数据的时候,它便会严重破坏你的表格数据,这可能是作者的无心之失,实验的数据可能全是满值的结果吧。这个问题想改也很容易,就是删除表格重新写入的过程。所以我构造这个对象的时候最后一个参数为false,我不需要有备份,这样便会省去删除表格又重新写的麻烦了。

    2 AddCell问题,四参数的那个:

    bool AddCell(CString CellValue, CString column, long row = 0, bool Auto = true);

    如果你想添加一个新列,就必须得到你想添加在哪一列,分析当最后一个参数添加新列的方式:

    (1)当最后一个参数为true时具体代号在EXCEL中可以看出,第一列是“A”,第二列为“B”,以此类推,传入的第二个参数必须是“A”、“B”...如果你想在没有数据的下一列生成新列,方法就是先用GetTotalColumns()获得总的列数,然后“A”代表65,新的一列的值为 65 + 总列数 - 1,再转换成ASCII字符传进去就OK了。

    (2)当最后一个参数为false时,第二个参数就只能传入列头了,比如xls表其中一个列头名为Age,则传入第二个参数就传入“Age”,只能代替原有表格的数据,但是当你想添加新列,列头名为Tel的时候,就不能做了,原因是作者没有考虑到最后一个参数为false的时候,添加新列的情况。

    这个问题也很简单,我做了如下修改,便可以用AddCell("Tel","Tel",0,false)用新表头来创建新列了,

bool CSpreadSheet::AddCell(CString CellValue, CString column, long row, bool Auto)
{
 short columnIndex = CalculateColumnNumber(column, Auto);
 if (columnIndex == 0)
 {

    columnIndex = m_aFieldNames.GetSize()+1;
 }

 if (AddCell(CellValue, columnIndex, row))
 {
  return true;
 }
 return false;
}

    这样修改的目的就是当在原有的列头中搜索,没有发现就认定为新的列,返回一个列的列号。

    3 第三个问题相信有很多朋友都遇到过,就是用cspreadsheet生成的表格,每个格子里的数据左上方会有一个上逗号的标志:“’” 虽然不影响读取数据,但影响了美观。

    起初我怀疑是写入表格的时候所有数据前有个多余的“’”符号,但我跟踪代码后并没有发现,后来找了个新的读写EXCEL的开源库 ExcelFormat_src,发现写入的也是有“’”符号,这两种都是用的数据库方式。所以,我断定这个数据库方式特点,“’”符号代表是字符串类型的。

    出现这个情况的原因就是CSpreadSheet将所有的数据类型都按一种称为万能类型的字符串类型,这种处理方式虽然简单,但是却忽略了每一列的数据类型,在数据库中每一列代表每一个字段。

    于是我将CSpreadSheet源代码修改了一下,用来区别开字符串类型和数字类型,加入了PUBLIC成员变量vector<BOOL> vecNumOrAlp;

    它的含义就是为了表征每一列的数据类型,FALSE时为字符串类型,TRUE为数值类型。

    然后修改AddRow函数的代码:

    将m_stempSql.Format("\"%s\"%s", RowValues.GetAt(i), m_sSeparator);替换为:

    if(!vecNumOrAlp[i])

        m_stempSql.Format("\"%s\"%s", RowValues.GetAt(i), m_sSeparator);

    else

    {

        float f = atof((LPCSTR)RowValues.GetAt(i));

        m_stempSql.Format("\"%.7f\"%s", f, m_sSeparator);

    }

    修改Commit()代码如下:

    将m_stempSql = m_stempSql + "[" + m_aFieldNames.GetAt(j) +"]" + " char(255), ";替换为:

   

    if(!vecNumOrAlp[i])

        m_stempSql = m_stempSql + "[" + m_aFieldNames.GetAt(j) +"]" + " text, ";

    else

         m_stempSql = m_stempSql + "[" + m_aFieldNames.GetAt(j) +"]" + " double, ";   

 

    经过如此修改,就可以区分出数值类型和字符串类型的,而且数字类型的左上角不会有”‘“符号了。当然,如果牵扯到其他类型,比如日期型,可以将vecNumOrAlp的BOOL类型改成结构体或枚举类型的,用来表征不同的数据类型。

    至此我所遇到的 CSpreadSheet问题都已经解决了,如果有朋友哪里有更好的建议或者不明白的,可以随时和我探讨,使CSpreadSheet用起来更加方便,更加完美。   关于使用cspreadsheet读写EXCEL表格数据的问题

 

 

    最近又发现点新问题,在这给大家分享一下!

    1 CSpreadSheet由于采用的是数据库方式,所以有一个字段数量限制,这是微软的ADO访问数据库的一个限制,最多255个字段,多了就不行了,详情请参照微软核心代码dbcore.一般情况下,是用不到这么多字段的,所以很少人能够发现,如果用到这么大的,很遗憾,只能选用其他的exl组件了。

    2 AddRow()函数问题。这个问题也有很多人没有注意到,它的效率极其低下!当然如果添加行数比较少的话,没什么影响,但是当你添加上百行数据的时候,这个函数的问题就凸现出来了。原因就在于AddRow()函数调用了Commit()。Commit()函数的步骤相信看过代码的人都能了解: 1 删除DROP表;2 创建CREATE TABLE表 ;3 往表里循环写数据。 也就是说每次添加行都要执行这3步,显然是不合理的,如果你只想添加第500行数据,但程序一定要将500行数据全部写入,这样效率就很低了。这个问题解释到这 解决方案很简单:每次添加新行时,不进行前两步,第三步也只写入新行。 代码就不在此贴出了,相信大多数人都会改,如果有人需要的话,也可以在我的博客留言。

这篇关于关于使用cspreadsheet读写EXCEL表格数据的问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1148071

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

10. 文件的读写

10.1 文本文件 操作文件三大类: ofstream:写操作ifstream:读操作fstream:读写操作 打开方式解释ios::in为了读文件而打开文件ios::out为了写文件而打开文件,如果当前文件存在则清空当前文件在写入ios::app追加方式写文件ios::trunc如果文件存在先删除,在创建ios::ate打开文件之后令读写位置移至文件尾端ios::binary二进制方式

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件