a
This commit is contained in:
@@ -0,0 +1,251 @@
|
||||
# 数据导出与导入
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [ioexpdlg.cpp](file://cpp/Views/ioexpdlg.cpp)
|
||||
- [ioexpdmsdlg.cpp](file://cpp/Views/ioexpdmsdlg.cpp)
|
||||
- [ioexpsptdlg.cpp](file://cpp/Views/ioexpsptdlg.cpp)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp)
|
||||
- [DialMeasureData.cpp](file://cpp/Views/DialMeasureData.cpp)
|
||||
- [DownloadDataProgressDlg.cpp](file://cpp/Views/DownloadDataProgressDlg.cpp)
|
||||
- [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp)
|
||||
- [OperUrfFile.cpp](file://cpp/Tools/OperUrfFile.cpp)
|
||||
- [excel.cpp](file://cpp/Tools/excel.cpp)
|
||||
- [ioexpdlg.h](file://h/ioexpdlg.h)
|
||||
- [ioexpdmsdlg.h](file://h/ioexpdmsdlg.h)
|
||||
- [ioexpsptdlg.h](file://h/ioexpsptdlg.h)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [数据导出功能架构](#数据导出功能架构)
|
||||
3. [导出对话框与用户交互](#导出对话框与用户交互)
|
||||
4. [IOManager协调机制](#iomanager协调机制)
|
||||
5. [文件操作工具实现](#文件操作工具实现)
|
||||
6. [导出流程与进度反馈](#导出流程与进度反馈)
|
||||
7. [用户操作指南](#用户操作指南)
|
||||
8. [开发者扩展指南](#开发者扩展指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 引言
|
||||
|
||||
Geomative Studio软件提供了一套完整的数据导出与导入功能,旨在支持地质勘探数据在不同格式间的转换与共享。本系统化文档详细说明了`ioexpdlg`、`ioexpdmsdlg`和`ioexpsptdlg`三个核心对话框所支持的导出格式(包括Excel、CSV、TXT、URF)及其底层实现逻辑。文档深入解析了`IOManager`如何作为中央协调者,调用`OperTxtFile`、`OperUrfFile`和`excel`等专用文件操作工具来完成复杂的数据转换与文件生成任务。
|
||||
|
||||
此外,本文档阐述了从`DialMeasureData`对话框触发的完整导出流程,以及`DownloadDataProgressDlg`提供的实时进度反馈机制。为最终用户提供了关于如何选择导出范围、配置文件命名规则和验证导出完整性的详细操作说明。同时,为开发者提供了关于如何扩展支持新的导出格式(如JSON、PDF)、优化大数据量导出性能的缓冲策略,以及处理文件编码、跨平台换行符等兼容性问题的最佳实践。
|
||||
|
||||
**Section sources**
|
||||
- [ioexpdlg.cpp](file://cpp/Views/ioexpdlg.cpp#L1-L244)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L1-L2064)
|
||||
|
||||
## 数据导出功能架构
|
||||
|
||||
Geomative Studio的数据导出功能采用分层架构设计,由用户界面层、业务逻辑层和数据访问层协同工作。核心组件`IOManager`位于业务逻辑层,负责协调整个导出流程。当用户通过`DialMeasureData`等界面组件发起导出请求时,控制权会传递给`IOManager`。
|
||||
|
||||
`IOManager`首先通过`CIOExpDlg`对话框收集用户的导出选项,包括选择要导出的项目、测区和测点数据。随后,它根据用户的选择,调用相应的数据提取和转换逻辑。对于数据库导出,`IOManager`使用ADOX库创建一个新的Access数据库文件(.accdb),并定义其表结构。然后,它将选定的数据从主数据库中提取出来,并插入到新创建的导出文件中。
|
||||
|
||||
对于其他格式(如TXT、URF、Excel),`IOManager`会实例化对应的文件操作工具类(如`OperTxtFile`、`OperUrfFile`、`excel`),并将数据流传递给它们进行格式化和写入。这种设计实现了关注点分离,使得`IOManager`可以专注于流程控制,而具体的文件格式实现则由专门的工具类负责。
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[用户界面] --> B[IOManager]
|
||||
B --> C[数据提取]
|
||||
C --> D[格式转换]
|
||||
D --> E[文件生成]
|
||||
E --> F[导出文件]
|
||||
B --> G[OperTxtFile]
|
||||
B --> H[OperUrfFile]
|
||||
B --> I[excel]
|
||||
G --> E
|
||||
H --> E
|
||||
I --> E
|
||||
```
|
||||
|
||||
**Diagram sources **
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L35-L98)
|
||||
- [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp#L19-L35)
|
||||
- [OperUrfFile.cpp](file://cpp/Tools/OperUrfFile.cpp#L19-L29)
|
||||
- [excel.cpp](file://cpp/Tools/excel.cpp#L1-L800)
|
||||
|
||||
**Section sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L35-L98)
|
||||
- [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp#L19-L35)
|
||||
- [OperUrfFile.cpp](file://cpp/Tools/OperUrfFile.cpp#L19-L29)
|
||||
- [excel.cpp](file://cpp/Tools/excel.cpp#L1-L800)
|
||||
|
||||
## 导出对话框与用户交互
|
||||
|
||||
数据导出功能通过一系列对话框与用户进行交互,其中`CIOExpDlg`是主对话框,它整合了`CIOExpDmsDlg`和`CIOExpSptDlg`两个子对话框,分别用于选择数据(项目、测区、测点)和脚本。
|
||||
|
||||
### CIOExpDlg 主对话框
|
||||
|
||||
`CIOExpDlg`继承自`CDialog`,其主要职责是提供一个选项卡式界面,让用户在“数据”和“脚本”两个选项卡之间切换。当用户点击“确定”按钮时,该对话框会检查用户是否在任一选项卡中选择了要导出的项目。如果未选择任何项目,会弹出提示框要求用户选择。如果选择了项目,则会弹出文件保存对话框,让用户指定导出文件的路径和名称(默认为.accdb格式)。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CIOExpDlg {
|
||||
+CString m_szFileName
|
||||
+CIOExpDmsDlg m_ioDmsDlg
|
||||
+CIOExpSptDlg m_ioSptDlg
|
||||
-INT_PTR* m_pRet
|
||||
+CIOExpDlg(CWnd* pParent)
|
||||
+CIOExpDlg(INT_PTR* pRet, CWnd* pParent)
|
||||
+virtual BOOL Create(UINT nID, CWnd* pParentWnd)
|
||||
+virtual void OnOK()
|
||||
+virtual void OnCancel()
|
||||
+virtual BOOL OnInitDialog()
|
||||
+afx_msg void OnSelchangeIoExpTab(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
}
|
||||
class CIOExpDmsDlg {
|
||||
+CTreeCtrl m_dmsTree
|
||||
+CIOExpDmsDlg(CWnd* pParent)
|
||||
+virtual BOOL OnInitDialog()
|
||||
+afx_msg void OnShowWindow(BOOL bShow, UINT nStatus)
|
||||
+afx_msg void OnClickTreeExpDms(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
+afx_msg void OnSelchangingTreeExpDms(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
}
|
||||
class CIOExpSptDlg {
|
||||
+CListCtrl m_sptList
|
||||
+CIOExpSptDlg(CWnd* pParent)
|
||||
+virtual BOOL OnInitDialog()
|
||||
+afx_msg void OnShowWindow(BOOL bShow, UINT nStatus)
|
||||
}
|
||||
CIOExpDlg --> CIOExpDmsDlg : "包含"
|
||||
CIOExpDlg --> CIOExpSptDlg : "包含"
|
||||
```
|
||||
|
||||
**Diagram sources **
|
||||
- [ioexpdlg.h](file://h/ioexpdlg.h#L16-L56)
|
||||
- [ioexpdmsdlg.h](file://h/ioexpdmsdlg.h#L13-L44)
|
||||
- [ioexpsptdlg.h](file://h/ioexpsptdlg.h#L13-L42)
|
||||
|
||||
### CIOExpDmsDlg 数据选择对话框
|
||||
|
||||
`CIOExpDmsDlg`使用一个`CTreeCtrl`(树形控件)来展示项目、测区和测点的层级结构。用户可以通过点击树节点旁的复选框来选择要导出的数据。该对话框在初始化时会设置树形控件的样式,使其显示连接线和按钮。`OnClickTreeExpDms`消息处理函数实现了智能的复选框逻辑:当用户选中一个父节点时,其所有子节点也会被自动选中;当用户取消选中一个父节点时,其所有子节点也会被取消选中。
|
||||
|
||||
### CIOExpSptDlg 脚本选择对话框
|
||||
|
||||
`CIOExpSptDlg`使用一个`CListCtrl`(列表控件)来展示所有可用的脚本。该控件被配置为支持全行选择、拖拽列头、网格线和复选框。在`OnInitDialog`函数中,它会动态地从资源文件中加载列标题(如“脚本编号”、“脚本名称”、“电极数量”等),并创建相应的列。
|
||||
|
||||
**Section sources**
|
||||
- [ioexpdlg.cpp](file://cpp/Views/ioexpdlg.cpp#L1-L244)
|
||||
- [ioexpdmsdlg.cpp](file://cpp/Views/ioexpdmsdlg.cpp#L1-L145)
|
||||
- [ioexpsptdlg.cpp](file://cpp/Views/ioexpsptdlg.cpp#L1-L115)
|
||||
- [ioexpdlg.h](file://h/ioexpdlg.h#L1-L62)
|
||||
- [ioexpdmsdlg.h](file://h/ioexpdmsdlg.h#L1-L50)
|
||||
- [ioexpsptdlg.h](file://h/ioexpsptdlg.h#L1-L48)
|
||||
|
||||
## IOManager协调机制
|
||||
|
||||
`IOManager`是整个数据导出功能的核心协调者。它通过`Export`方法启动导出流程。该方法首先创建并显示`CIOExpDlg`对话框,等待用户完成选择。一旦用户确认,`IOManager`会根据用户选择的文件路径,调用`CreateExpDatabase`方法创建一个新的Access数据库文件,并定义其表结构(如project、tz、td等)。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User as 用户
|
||||
participant CIOExpDlg as CIOExpDlg
|
||||
participant IOManager as IOManager
|
||||
participant Database as 数据库
|
||||
participant File as 文件系统
|
||||
User->>CIOExpDlg : 点击“导出”
|
||||
CIOExpDlg->>CIOExpDlg : 显示对话框
|
||||
User->>CIOExpDlg : 选择数据并点击“确定”
|
||||
CIOExpDlg->>IOManager : 返回文件路径
|
||||
IOManager->>IOManager : 创建导出数据库
|
||||
IOManager->>Database : 提取选定数据
|
||||
Database-->>IOManager : 返回数据
|
||||
IOManager->>File : 写入数据到.accdb文件
|
||||
File-->>IOManager : 写入完成
|
||||
IOManager-->>User : 显示成功消息
|
||||
```
|
||||
|
||||
**Diagram sources **
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L35-L98)
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L206-L656)
|
||||
|
||||
**Section sources**
|
||||
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L35-L98)
|
||||
|
||||
## 文件操作工具实现
|
||||
|
||||
### OperTxtFile 文本文件操作
|
||||
|
||||
`OperTxtFile`类负责将数据导出为纯文本(TXT)格式。它提供了一个`SetParamWidth`方法来设置每个字段的宽度,确保导出的文本文件具有整齐的列对齐。`OpenFileforWrite`方法用于打开或创建一个文本文件。`WriteFileContent`方法接收一个`CStringArray`,将数组中的每个字符串按照设定的宽度填充空格后写入文件,不足宽度的部分用空格补齐,每个数组元素写入后会自动添加换行符。
|
||||
|
||||
### OperUrfFile URF文件操作
|
||||
|
||||
`OperUrfFile`类专门用于生成通用电阻率数据文件(URF)。它支持多种电极阵列类型,如温纳-施伦贝谢(Wenner-Schlumberger)、跨孔(Cross-Hole)等。`WriteElecByAR`方法是核心,它根据传入的阵列类型(iAR)参数,调用不同的私有方法(如`WriteElecByWenSch`、`WriteElecByCrossHole`)来生成符合特定阵列几何形状的电极坐标。URF文件的头部包含固定的注释和单位信息。
|
||||
|
||||
### Excel 文件操作
|
||||
|
||||
`excel.cpp`文件包含通过MFC的`COleDispatchDriver`包装类与Microsoft Excel应用程序进行交互的代码。这些包装类(如`_Application`、`_Workbook`、`_Worksheet`)允许程序以自动化的方式创建Excel工作簿、写入数据、设置单元格格式等。虽然具体的导出逻辑未在提供的代码片段中完全展示,但可以推断`IOManager`会使用这些类来将数据写入Excel的单元格中,并生成.xlsx或.xls文件。
|
||||
|
||||
**Section sources**
|
||||
- [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp#L1-L166)
|
||||
- [OperUrfFile.cpp](file://cpp/Tools/OperUrfFile.cpp#L1-L800)
|
||||
- [excel.cpp](file://cpp/Tools/excel.cpp#L1-L800)
|
||||
|
||||
## 导出流程与进度反馈
|
||||
|
||||
### 从DialMeasureData触发导出
|
||||
|
||||
数据导出流程通常从`DialMeasureData`对话框开始,该对话框是用户进行测量操作的主要界面。当用户完成测量并希望导出数据时,可以通过菜单或按钮触发导出功能。`DialMeasureData`类本身不直接处理导出,而是通过调用`IOManager`的`Export`方法来启动整个流程。
|
||||
|
||||
### DownloadDataProgressDlg 进度反馈
|
||||
|
||||
在执行耗时较长的导出或导入操作时,系统会显示`DownloadDataProgressDlg`对话框来提供进度反馈。该对话框在初始化时会启动一个工作线程(`DownloadThread`或`UploadThread`),以避免阻塞主UI线程。工作线程会定期调用`ShowProcessPercent`方法,该方法根据已完成的工作量计算百分比,并更新对话框上的进度标签。这确保了用户界面的响应性,并让用户清楚地了解操作的进展情况。
|
||||
|
||||
**Section sources**
|
||||
- [DialMeasureData.cpp](file://cpp/Views/DialMeasureData.cpp#L1-L800)
|
||||
- [DownloadDataProgressDlg.cpp](file://cpp/Views/DownloadDataProgressDlg.cpp#L1-L479)
|
||||
|
||||
## 用户操作指南
|
||||
|
||||
### 选择导出范围
|
||||
|
||||
1. 在软件主界面,导航到需要导出数据的项目。
|
||||
2. 右键点击项目、测区或测点,选择“导出”选项。
|
||||
3. 在弹出的“数据导出”对话框中,切换到“数据”选项卡。
|
||||
4. 在树形结构中,勾选您想要导出的项目、测区和测点。勾选父节点会自动包含其所有子节点。
|
||||
5. 切换到“脚本”选项卡,勾选您想要导出的脚本。
|
||||
|
||||
### 配置文件命名规则
|
||||
|
||||
1. 完成选择后,点击“确定”。
|
||||
2. 系统会弹出“另存为”对话框。
|
||||
3. 在“文件名”输入框中,输入您希望的文件名。
|
||||
4. 系统默认的文件扩展名为`.accdb`,您也可以选择其他格式(如果功能支持)。
|
||||
5. 选择保存位置,然后点击“保存”。
|
||||
|
||||
### 验证导出完整性
|
||||
|
||||
1. 导出完成后,系统会显示“导出成功”的提示。
|
||||
2. 前往您指定的保存位置,找到导出的文件。
|
||||
3. 打开文件(例如,用Access打开.accdb文件,用文本编辑器打开.txt文件)。
|
||||
4. 检查文件内容是否与您在导出对话框中选择的数据范围一致,确保所有必要的数据都已包含在内。
|
||||
|
||||
## 开发者扩展指南
|
||||
|
||||
### 新增导出格式(如JSON、PDF)
|
||||
|
||||
要支持新的导出格式,开发者需要遵循以下步骤:
|
||||
1. **创建新的工具类**:创建一个名为`OperJsonFile`或`OperPdfFile`的新类,类似于`OperTxtFile`和`OperUrfFile`。
|
||||
2. **实现核心方法**:在新类中实现`OpenFile`、`WriteData`和`CloseFile`等核心方法。对于JSON,可以使用第三方库(如nlohmann/json)来构建和序列化JSON对象。对于PDF,可以使用库(如libHaru或PoDoFo)来创建PDF文档并写入表格数据。
|
||||
3. **扩展IOManager**:在`IOManager`类中添加新的导出方法(如`ExportToJSON`、`ExportToPDF`),并在`Export`方法中根据用户选择的格式调用相应的方法。
|
||||
4. **更新用户界面**:在“另存为”对话框的文件类型过滤器中添加新的格式选项(如`JSON Files (*.json)|*.json||`)。
|
||||
|
||||
### 优化大数据量导出性能
|
||||
|
||||
对于大数据量的导出,应采用缓冲和分块处理策略:
|
||||
1. **分批读取**:不要一次性将所有数据加载到内存中。使用数据库的分页查询(如`LIMIT`和`OFFSET`)或游标,分批读取数据。
|
||||
2. **缓冲写入**:在文件操作工具中,使用缓冲区(buffer)来累积一定量的数据后再写入磁盘,减少I/O操作次数。
|
||||
3. **异步处理**:将导出操作放在后台线程中执行,避免阻塞UI。`DownloadDataProgressDlg`的实现已经展示了如何使用`AfxBeginThread`来实现这一点。
|
||||
|
||||
### 处理兼容性问题
|
||||
|
||||
1. **文件编码**:对于文本文件(TXT、CSV),应明确指定编码格式(如UTF-8)。在`OperTxtFile`中,可以修改`fopen`调用,使用`"w+, ccs=UTF-8"`来确保文件以UTF-8编码保存,避免中文乱码。
|
||||
2. **跨平台换行符**:Windows使用`\r\n`,而Unix/Linux使用`\n`。在`OperTxtFile`的`WriteFileContent`方法中,可以根据目标平台动态选择换行符。可以通过编译宏(如`_WIN32`)来判断当前平台。
|
||||
|
||||
## 结论
|
||||
|
||||
Geomative Studio的数据导出与导入功能通过清晰的分层架构和模块化设计,实现了高效、可靠的数据交换。`IOManager`作为核心协调者,有效地整合了用户界面、数据访问和文件生成等多个组件。通过分析`ioexpdlg`系列对话框和`OperTxtFile`、`OperUrfFile`等工具类,我们理解了系统如何支持多种导出格式并提供良好的用户体验。
|
||||
|
||||
本文档不仅为用户提供了清晰的操作指南,也为开发者指明了扩展和优化的方向。通过遵循本文档中的最佳实践,可以确保新功能的顺利集成,并持续提升软件在处理复杂地质数据方面的专业性和可靠性。
|
||||
Reference in New Issue
Block a user