#include "xlsxhandler.h" #include "logger.h" #include "analysisoperationrecorder.h" #include "global.h" namespace AnaOpRecorder = AnalysisOperationRecorder; using AnaOpRecorderOperation = AnalysisOperationRecorder::AnalysisOperation; QString XlsxHandler::_currentFilePath; void XlsxHandler::test() { #if 0 QString sourceFilePath = QDir::currentPath() + "/sample.xlsx"; qDebug() << "fileName:" << sourceFilePath; readFile(sourceFilePath); #endif QString sourceFilePath = QDir::currentPath() + "/sample-save.xlsx"; writeFile(sourceFilePath); } int XlsxHandler::readFile(const QString sourceFilePath, Global::CurveFileData &cfd) { if(!QFile::exists(sourceFilePath)) { qDebug() << "xlsx file not existed:" << sourceFilePath; return 1; } QFileInfo fileInfo(sourceFilePath); // 获取文件的后缀名并转换为小写,方便比较 QString fileSuffix = fileInfo.suffix().toLower(); // 判断后缀名是否为 "xlsx" if (fileSuffix != "xlsx") { std::cout << "该文件的后缀不是 xlsx" << std::endl; return 2; } _currentFilePath = sourceFilePath; QXlsx::Document xlsx(sourceFilePath); QXlsx::Worksheet *workSheet = xlsx.currentWorksheet(); if(!workSheet) { logde << "current sheet is empty."; return 3; } // int index = 2; Global::ExperimentInfo& ei = cfd.ei; ei.sampleName = workSheet->cellAt(index++, 2)->value().toString(); ei.sampleWeight = workSheet->cellAt(index++, 2)->value().toString(); logde<<"xlsx sample weight:"<cellAt(index++, 2)->value().toString(); ei.experimentor = workSheet->cellAt(index++, 2)->value().toString(); index++; // skip measure type. ei.phaseSize = workSheet->cellAt(index++, 2)->value().toInt(); QVector& phaseTotalVtr = cfd.phaseTotalVtr; int dataIndex = 9; for(int i = 0; i < ei.phaseSize; i++) { Global::PhaseTotalInfo phaseTotal; phaseTotal.phaseIndex = i + 1; readPhaseData(workSheet, dataIndex, phaseTotal); phaseTotalVtr.push_back(phaseTotal); } logde<<"dataIndex:"<cellAt(startLineIndex++, 2)->value().toDouble(); phaseTotal.phase.temp_flow = workSheet->cellAt(startLineIndex++, 2)->value().toDouble(); phaseTotal.phase.constant_temp_time_min = (uint16_t)(workSheet->cellAt(startLineIndex++, 2)->value().toInt()); phaseTotal.phase.gas = static_cast(workSheet->cellAt(startLineIndex++, 2)->value().toInt()); int dataSize = workSheet->cellAt(startLineIndex++, 2)->value().toInt(); logde<<"data size:"<cellAt(startLineIndex, 2)->value().toDouble(); data.sampleTemp = workSheet->cellAt(startLineIndex, 3)->value().toDouble(); data.dsc = workSheet->cellAt(startLineIndex, 4)->value().toDouble(); phaseTotal.dataVtr.push_back(data); startLineIndex++; } } void XlsxHandler::writeFile(const QString filePath) { Global::ExperimentInfo& ei = Global::_experimentInfo; QXlsx::Document xlsx; xlsx.addSheet("Sheet1"); // 添加一个新的工作表 // Write experiment info. int row = 1; xlsx.write(row++ , 1, ConFileDataInfo); xlsx.write(row , 1, ConSampleName); QString sampleName = ei.sampleName; if(sampleName.isEmpty()){ sampleName = "sample"; } xlsx.write(row , 2, sampleName); row++; xlsx.write(row , 1, ConSampleWeight); QString sampleWeight = ei.sampleWeight; if(sampleWeight.isEmpty()){ sampleWeight = "1"; } xlsx.write(row , 2, sampleWeight); xlsx.write(row , 3, ConUnitMg); row++; xlsx.write(row , 1, ConCrucibleWeight); xlsx.write(row , 2, 0); xlsx.write(row , 3, ConUnitMg); row++; xlsx.write(row , 1, Conexperimenter); QString experimentor = ei.experimentor; if(experimentor.isEmpty()){ experimentor = "experimentor"; } xlsx.write(row , 2, experimentor); row++; xlsx.write(row , 1, ConDate); QString date = ei.date; if(date.isEmpty()){ date = "20250101"; } xlsx.write(row , 2, date); row++; xlsx.write(row , 1, ConMeasureType); xlsx.write(row , 2, "样品"); row++; int phaseSizeRow = row; int phaseCount = 0; xlsx.write(row , 1, ConPhaseSize); xlsx.write(row , 2, ei.phaseVtr.size()); row++; // Write phase data. int dataSizeRow = 0; logde<<"phase vtr size:"<& edVtr = Global::_curveExperimentDataVtr.at(i).dataVtr; // phase data size. dataSizeRow = row; xlsx.write(row , 1, ConPhaseDataSize); xlsx.write(row , 2, edVtr.size()); row++; logde<<"edVtr size:"<currentWorksheet(); if(!sheet) { logde << "current sheet is empty."; return; } int index = sheet->dimension().lastRow(); logde<<"lastRow:"<& aoVtr = AnalysisOperationRecorder::_ananlysisOperationVtr; xlsx->write(row , 1, ConAnalysisOperationCount); xlsx->write(row , 2, aoVtr.size()); row++; for (AnaOpRecorderOperation& ao:aoVtr){ QString analysisOpName; switch(ao.mode){ case Global::NumericalLabel: { analysisOpName = AnalysisOperationRecorder::NumericalLabelStr; break; } case Global::StartPoint: { analysisOpName = AnalysisOperationRecorder::StartPointStr; break; } case Global::StopPoint: { analysisOpName = AnalysisOperationRecorder::StopPointStr; break; } case Global::PeakSynthesisAnalysis: { analysisOpName = AnalysisOperationRecorder::PeakSynthesisAnalysisStr; break; } case Global::GlassTransition: { analysisOpName = AnalysisOperationRecorder::GlassTransitionStr; break; } case Global::OnsetTemperaturePoint: { analysisOpName = AnalysisOperationRecorder::OnsetTemperaturePointStr; break; } case Global::EndsetTemperaturePoint: { analysisOpName = AnalysisOperationRecorder::EndsetTemperaturePointStr; break; } default:break; } xlsx->write(row , 1, analysisOpName); xlsx->write(row , 2, ao.x1); xlsx->write(row , 3, ao.x2); row++; } // save #if 1 if (!xlsx->saveAs(filePath)) { logde<<"Save xlsx failed."; delete xlsx; return ; } #endif #if 0 if (!xlsx->saveAs(filePath)) { qDebug() << "Failed to save xlsx file:" << filePath; // 检查和创建目录 QDir dir(filePath); if (!dir.exists()) { qDebug() << "Directory does not exist. Creating directory..."; dir.mkpath("."); } // 检查权限 QFile file(filePath); if (!file.open(QIODevice::WriteOnly)) { qDebug() << "Permission denied:" << file.errorString(); } // 检查磁盘空间 QStorageInfo storageInfo(QDir::rootPath()); if (storageInfo.bytesFree() < 1024 * 1024 * 10) { // 假设文件大小至少为10MB qDebug() << "Disk space is insufficient."; } // 尝试重新保存 if (!xlsx->saveAs(filePath)) { qDebug() << "Save xlsx failed after retrying."; } } #endif // delete xlsx; logde<<"Save xlsx succ."; } QXlsx::Document* XlsxHandler::openXlsxFile(const QString& sourceFilePath) { // 检查文件是否存在 if (!QFile::exists(sourceFilePath)) { qDebug() << "xlsx file not existed:" << sourceFilePath; return nullptr; } QFileInfo fileInfo(sourceFilePath); // 获取文件的后缀名并转换为小写,方便比较 QString fileSuffix = fileInfo.suffix().toLower(); // 判断后缀名是否为 "xlsx" if (fileSuffix != "xlsx") { std::cout << "该文件的后缀不是 xlsx" << std::endl; return nullptr; } QXlsx::Document* xlsx = new QXlsx::Document(sourceFilePath); QXlsx::Worksheet* workSheet = xlsx->currentWorksheet(); if (!workSheet) { qDebug() << "current sheet is empty."; delete xlsx; return nullptr; } return xlsx; } void XlsxHandler::readAnalysisOperation(QXlsx::Worksheet *sheet, int &startLineIndex) { int size = sheet->cellAt(startLineIndex++, 2)->value().toInt(); logde<<"ana op size:"<cellAt(startLineIndex, 1)->value().toString(); if(modeStr == AnaOpRecorder::NumericalLabelStr){ ao.mode = Global::AnalysisMode::NumericalLabel; }else if(modeStr == AnaOpRecorder::StartPointStr){ ao.mode = Global::AnalysisMode::StartPoint; }else if(modeStr == AnaOpRecorder::StopPointStr){ ao.mode = Global::AnalysisMode::StopPoint; }else if(modeStr == AnaOpRecorder::PeakSynthesisAnalysisStr){ ao.mode = Global::AnalysisMode::PeakSynthesisAnalysis; }else if(modeStr == AnaOpRecorder::GlassTransitionStr){ ao.mode = Global::AnalysisMode::GlassTransition; }else if(modeStr == AnaOpRecorder::OnsetTemperaturePointStr){ ao.mode = Global::AnalysisMode::OnsetTemperaturePoint; }else if(modeStr == AnaOpRecorder::EndsetTemperaturePointStr){ ao.mode = Global::AnalysisMode::EndsetTemperaturePoint; } ao.x1 = sheet->cellAt(startLineIndex, 2)->value().toDouble(); ao.x2 = sheet->cellAt(startLineIndex, 3)->value().toDouble(); AnaOpRecorder::_fileAnanlysisOperationVtr.push_back(ao); startLineIndex++; logde<<" ao mode:"<