Files
geomative/GeomativeStudio/.qoder/repowiki/zh/content/核心功能/测试数据管理/数据导出.md
T
coco df489d5640 a
2026-07-03 16:05:30 +08:00

11 KiB
Raw Blame History

数据导出

**本文档引用的文件** - [TdManager.cpp](file://cpp/Managers/TdManager.cpp) - [IOManager.cpp](file://cpp/Managers/IOManager.cpp) - [excel.cpp](file://cpp/Tools/excel.cpp) - [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp) - [OperUrfFile.cpp](file://cpp/Tools/OperUrfFile.cpp) - [DataOperator.cpp](file://cpp/Operator/DataOperator.cpp) - [Rsp2DTd.cpp](file://cpp/ProblemZone/Rsp2DTd.cpp) - [RspCETd.cpp](file://cpp/ProblemZone/RspCETd.cpp) - [SP2DTd.cpp](file://cpp/ProblemZone/SP2DTd.cpp) - [TdManager.h](file://h/TdManager.h) - [IOManager.h](file://h/IOManager.h) - [excel.h](file://h/excel.h) - [OperTxtFile.h](file://h/OperTxtFile.h) - [OperUrfFile.h](file://h/OperUrfFile.h) - [ioexpdlg.cpp](file://cpp/Views/ioexpdlg.cpp) - [ioexpdmsdlg.cpp](file://cpp/Views/ioexpdmsdlg.cpp) - [ioexpsptdlg.cpp](file://cpp/Views/ioexpsptdlg.cpp) - [ioexpdlg.h](file://h/ioexpdlg.h) - [ioexpdmsdlg.h](file://h/ioexpdmsdlg.h) - [ioexpsptdlg.h](file://h/ioexpsptdlg.h)

目录

  1. 引言
  2. 核心组件分析
  3. 数据导出格式与数据结构映射
  4. Excel导出功能实现
  5. 用户自定义导出选项处理
  6. 导出过程中的进度反馈与错误处理
  7. 大文件生成的内存优化方案

引言

本文档旨在全面文档化Geomative Studio软件中测试数据导出功能的实现。该功能主要由CTdManagerCIOManager两个核心管理类协同工作,支持将测试数据导出为Excel、CSV、TXT、URF等多种格式。文档将详细阐述其技术细节,包括不同格式的数据结构映射规则、用户自定义选项的处理逻辑、Excel导出中excel.cpp类库的使用流程,以及导出过程中的进度反馈、错误处理和内存优化策略。

核心组件分析

CTdManagerCIOManager是实现数据导出功能的两个核心类。

CTdManager类(位于cpp/Managers/TdManager.cpp)是测试数据的管理核心。它负责从数据库中获取测试数据,并提供将数据保存为特定文件格式的接口。例如,CRsp2DTdCRspCETd等具体的数据类型类继承自CTestingData,并实现了SaveTdToExcelFileSaveTdToCsvFile等方法,这些方法定义了如何将特定类型的数据组织并写入文件。

CIOManager类(位于cpp/Managers/IOManager.cpp)则负责更高层次的导出流程控制。其Export方法启动导出流程,创建一个导出对话框(CIOExpDlg),用户可以在其中选择要导出的项目、测区和具体的测试数据。CIOManager根据用户的选择,调用CTdManager提供的接口来执行实际的数据导出操作。

Section sources

数据导出格式与数据结构映射

系统支持将测试数据导出为四种主要格式:Excel、CSV、TXT和URF。每种格式都有其特定的数据结构映射规则。

对于Excel和CSV格式,数据通常被组织成多个工作表或数据块。以CRsp2DTd类为例,其SaveTdToExcelFile方法会创建一个Excel工作簿,并包含三个工作表:

  1. Head (头部信息): 包含测试任务的元数据,如任务名称、位置、日期、设备信息等。
  2. DAT (数据信息): 包含核心的测量数据,如电极配置(A, B, M, N)、视电阻率(Ro)、电压(V)、电流(I)等。
  3. GR (接地电阻): 包含各电极的接地电阻测量值。

TXT格式的导出由COperTxtFile类(位于cpp/Tools/OperTxtFile.cpp)处理。该类提供了一个可配置的文本文件写入器,通过SetParamWidth方法设置每列的宽度,并使用WriteFileContent方法将字符串数组按固定宽度写入文件,确保数据在文本编辑器中对齐。

URFUniversal Resistivity data File)是一种专用于电阻率数据的通用格式。其导出由COperUrfFile类(位于cpp/Tools/OperUrfFile.cpp)负责。URF文件的结构包括一个头部注释,然后是电极坐标信息,最后是测量数据。COperUrfFile类提供了针对不同电极阵列(如温纳装置、施伦贝谢装置、跨孔装置等)生成电极坐标的专用方法,如WriteElecByWenSchWriteElecByCrossHoleGeomative,确保导出的URF文件符合特定的地质勘探软件要求。

Section sources

Excel导出功能实现

Excel导出功能的核心是excel.cppexcel.h文件。这两个文件是通过Visual C++的ClassWizard工具从Microsoft Excel的类型库生成的C++包装类,它们提供了对Excel应用程序对象模型的COM接口访问。

导出过程遵循以下操作流程:

  1. 创建Excel应用实例:

    _Application* pComApp = new _Application;
    

    这行代码创建了一个Excel应用程序的COM对象实例。

  2. 创建和获取工作簿与工作表:

    Workbooks comBooks;
    _Workbook comBook;
    Sheets comSheets;
    _Worksheet comSheet01;
    

    通过_Application对象,可以获取Workbooks集合,进而创建一个新的工作簿(comBook),并从工作簿中获取Sheets集合来操作具体的工作表。

  3. 创建工作表并命名:

    comSheet01 = comSheets.GetItem(COleVariant((short)1));
    comSheet01.SetName(_T("Head"));
    

    使用GetItem方法获取第一个工作表,并使用SetName方法将其重命名为"Head"。

  4. 写入数据: 具体的数据写入逻辑由CTestingData的派生类(如CRsp2DTd)实现。这些类会调用SaveTdHeadToExcelFile等方法,通过遍历数据库记录集(_RecordsetPtr),并将数据逐行写入到_Worksheet对象的单元格中。

  5. 应用样式和公式: 虽然在提供的代码片段中未直接体现,但_WorksheetRange对象提供了丰富的属性和方法来设置单元格格式(如字体、颜色、边框)和应用公式。例如,可以通过GetRange方法获取一个单元格区域,然后设置其NumberFormat属性来定义数字显示格式。

  6. 保存并清理:

    comBook.SaveAs(COleVariant(f_szFileName), covOptional, ...);
    ...
    pComApp->Quit();
    delete pComApp;
    

    使用SaveAs方法将工作簿保存到指定路径。最后,必须显式调用Quit方法退出Excel应用,并释放所有COM对象指针,以避免内存泄漏。

Section sources

用户自定义导出选项处理

用户自定义导出选项主要通过导出对话框(CIOExpDlg)来处理。该对话框由CIOManagerExport方法中创建。

  1. 字段选择: 对话框中的树形控件(CTreeCtrl)允许用户通过复选框选择要导出的具体项目、测区和测试数据。CIOManager通过遍历树形控件,检查每个节点的选中状态,来确定最终需要导出的数据集。

  2. 时间范围和单位系统: 在提供的代码中,时间范围和单位系统的处理逻辑并未直接体现。这些选项很可能在CTestingData类的SaveTdTo...File方法内部实现。当从数据库查询数据时,会根据用户在UI中选择的时间范围构建SQL查询语句的WHERE子句。单位系统(如米/英尺)的转换则可能在数据写入文件之前,在内存中对数值进行换算。

Section sources

导出过程中的进度反馈与错误处理

进度反馈

在提供的代码中,导出过程是同步执行的,没有明确的进度条或百分比反馈机制。整个过程在用户点击“确定”后,直到完成或出错才会返回控制权。更完善的实现可能需要在CIOManagerCTdManager中引入后台线程,并通过Windows消息或回调函数向UI发送进度更新。

错误处理

系统采用了多层次的错误处理策略:

  1. 文件操作错误: 在打开或写入文件时,会检查返回值(如fopen是否返回NULL)。如果失败,会通过AfxMessageBoxMessageBoxEx向用户显示错误信息,包括错误代码(GetLastError())。
  2. 数据库操作错误: 使用try-catch块捕获_com_error异常,当执行数据库查询或操作失败时,会弹出错误对话框。
  3. 逻辑错误: 在执行关键操作前进行参数验证。例如,COperTxtFile::SetParamWidth会检查输入的宽度是否在有效范围内(6-50),否则会提示错误。
  4. COM接口错误: 在使用excel.cpp进行Excel操作时,虽然代码中没有显式捕获异常,但应假设_Application等对象的方法调用可能失败,需要进行返回值检查。

Section sources

大文件生成的内存优化方案

对于大文件的生成,系统主要通过以下方式优化内存使用:

  1. 流式写入 (Streaming): 所有文件导出操作都采用流式写入。无论是TXT、CSV还是URF文件,代码都是在打开文件后,一边从数据库读取记录,一边立即写入文件流(fwrite),然后立即处理下一条记录。这种方式避免了将整个数据集加载到内存中,从而将内存占用保持在较低水平。
  2. 分块处理: 数据库查询使用_RecordsetPtr,它本质上是一个游标,允许逐行遍历结果集,而不是一次性将所有数据加载到内存。
  3. 及时释放资源: 在操作完成后,代码会显式关闭文件句柄(fclose)、关闭数据库记录集(Close())并释放COM对象(ReleaseDispatch()),确保资源被及时回收。

Section sources