由于采样不提供导出到HMI的函数,需要自行编写:
1.在头文件中添加定义(注意自定义方法添加的位置,如下)
/*CUSTOM_CODE_BEGIN*/
void exportCSV(const string& sids,int ymdstart,int ymdend, const string& dircsv);
/*CUSTOM_CODE_END*/
/**
* @HideCA
* @brief 导出指定id及日期范围的采样数据到csv
* @param sids 多个采样id用逗号分隔,如 "1,2,3"。为空时,表示全部
* @param ymdstart 要导出的开始日期yyyyMMdd(从0:0:0开始)
* @param ymdend 要导出的结束日期yyyyMMdd(到23:59:59结束)
* @param dircsv 导出csv的目录(要确保目录存在,导出文件名不变,扩展名为csv)
* @note 如全部导出到U盘目录的"export下":exportCSV("",0,99999999,"export");注意要确保目录存在
* 模拟器中导出在【数据】目录下,而不是U盘
* 初次采样要采1分钟以上才会有数据(每采样1分钟,存盘1次)
*/
#include <dirent.h>
vector<string> vec1;//存放导出时的db文件路径
vector<string> vec2;//存放要导出的表名
vector<string> vec3;//存放导出的目标csv文件路径
void Frm01::exportCSV(const string& sids,int ymdstart,int ymdend, const string& dircsv) {
//1.找出所有采样数据库
IDatabase* db = DBMgr::getdb();
string sql = "SELECT SID, STBL, STORERULE, STORELIMIT, STOREFOLDER, STOREPLACE FROM S_SAMPLES WHERE SID IN ("+sids+")";
if(sids.empty())sql = "SELECT SID, STBL, STORERULE, STORELIMIT, STOREFOLDER, STOREPLACE FROM S_SAMPLES";
TTable dt = db->query(sql);//取采样的表名、有效期天数、导出数据的天数、导出文件夹路径、位置(HMI还是U盘)
if(dt.size()==0) {
return;
}
//2.ARM下核对输出路径
string exportpath = "./data/"; //默认WIN路径
#if __arm__
exportpath = dircsv;
if(!FileUtil::pathExists(exportpath))
FileUtil::createPath(exportpath);
#endif
//2.找出所有要导出的db文件
vec1.clear(); //db文件路径
vec2.clear(); //视图名
vec3.clear(); //csv文件路径
int rsize = dt.size();
for(int row = 0; row < rsize; row++) {
string sid = dt.getValue(row, 0); //sampleid
string tbname = dt.getValue(row, 1)+"_V"; //采样表的视图
string folder = dt.getValue(row, 4); //导出文件夹路径STOREFOLDER
string place = dt.getValue(row, 5); //存储介质(HMI还是U盘)
string folderPath; // 文件夹路径
//HMI的路径
folderPath = "/customer/usr/"+folder;
//创建/customer/usr目录
if(!FileUtil::pathExists("/customer/usr"))
FileUtil::createPath("/customer/usr");
//创建/customer/usr/+folder目录
if(!FileUtil::pathExists(folderPath))
FileUtil::createPath(folderPath);
int cntday = StringUtil::safeStoi(dt.getValue(row, 2));//
if(cntday>0) //分文件存储处理
{
//在文件夹中找到相应文件
DIR* directory = opendir(folderPath.c_str()); // 打开目录
if (directory != nullptr) {
dirent* file;
string reg = "^[0-9]{8}_SAMPLE_" + sid + ".db";
while ((file = readdir(directory)) != nullptr) {
string fn = file->d_name;
if(StringUtil::match(reg, fn)) {
string sdate = fn.substr(0, 8);
int ymd = StringUtil::safeStoi(sdate);
if(ymd>=ymdstart && ymd<=ymdend) {
vec1.emplace_back(folderPath + "/" + fn);
vec2.emplace_back(tbname);
fn=StringUtil::replace(fn, ".db", "");
vec3.emplace_back(exportpath + fn + ".csv");
}
}
}
closedir(directory); // 关闭目录
}
}
else
{
//单文件的,直接导出整个文件
vec1.emplace_back(folderPath + "/SAMPLE_" + sid+".db");
vec2.emplace_back(tbname);
vec3.emplace_back(exportpath + "SAMPLE_" + sid+".csv");
}
}
//3.开启线程导出
//使用异步worker
AsynWorker* worker=new AsynWorker(getRuntime()->getAppInstance(this_thread::get_id()));
worker->invoke([this](){
int l = vec1.size();
for(int i=0;i<l;i++) {
string pathdb = vec1[i];
string tbname = vec2[i];
string pathcsv = vec3[i];
string err = "1";//1表示成功
FileUtil::exportDB2CSV(pathdb, "tmpExportView", pathcsv, err);
}
#if __arm__
Util::exe("sync","w");
#endif
})->onFinished([this](){
string exportResult;
getRuntime()->getIPageMgr()->getMessageBox("导出完毕", MSGBOX_TYPE::TIP)->show();
});
worker->start();
}