欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。
📌 概述
导入导出模块用于数据的导入和导出。这个模块支持将应用数据导出为JSON或CSV格式,也支持从这些格式的文件中导入数据。通过Cordova框架,我们能够在Web层实现导入导出界面,同时利用OpenHarmony的文件系统能力处理文件操作。
导入导出模块采用了多格式支持设计,用户可以选择导出为JSON(完整数据)或CSV(表格数据)。导入时,应用会自动检测文件格式并进行相应的处理。
🔗 完整流程
导出流程:用户选择导出格式(JSON或CSV)和导出范围(全部数据或特定类型)。应用会收集相应的数据,转换为选定的格式,然后保存为文件。用户可以选择保存位置。
导入流程:用户选择要导入的文件。应用会读取文件内容,验证数据格式,然后将数据导入到数据库。导入前,应用会显示预览,让用户确认导入的数据。
数据映射流程:导入时,应用会自动将导入的数据字段映射到数据库字段。如果字段不匹配,用户可以手动配置映射关系。
🔧 Web代码实现
// 导出数据为JSONasyncfunctionexportAsJSON(dataType='all'){try{showLoading('正在导出数据...');letdata={};if(dataType==='all'||dataType==='diaries'){data.diaries=awaitdb.getAllDiaries();}if(dataType==='all'||dataType==='pets'){data.pets=awaitdb.getAllPets();}if(dataType==='all'||dataType==='categories'){data.categories=awaitdb.getAllCategories();}if(dataType==='all'||dataType==='tags'){data.tags=awaitdb.getAllTags();}constjsonData=JSON.stringify(data,null,2);constfileName=`pet-diary-export-${newDate().toISOString().split('T')[0]}.json`;awaitexportToFile(fileName,jsonData,'application/json');showSuccess('数据已导出');}catch(error){showError('导出失败: '+error.message);}}// 导出数据为CSVasyncfunctionexportAsCSV(dataType='diaries'){try{showLoading('正在导出数据...');letcsvData='';if(dataType==='diaries'){constdiaries=awaitdb.getAllDiaries();csvData=convertToCSV(diaries,['id','title','content','petName','date']);}elseif(dataType==='pets'){constpets=awaitdb.getAllPets();csvData=convertToCSV(pets,['id','name','breed','birthDate','gender']);}constfileName=`pet-diary-export-${dataType}-${newDate().toISOString().split('T')[0]}.csv`;awaitexportToFile(fileName,csvData,'text/csv');showSuccess('数据已导出');}catch(error){showError('导出失败: '+error.message);}}// 转换为CSV格式functionconvertToCSV(data,columns){constheaders=columns.join(',');constrows=data.map(item=>columns.map(col=>{constvalue=item[col];if(typeofvalue==='string'&&value.includes(',')){return`"${value}"`;}returnvalue;}).join(','));return[headers,...rows].join('\n');}// 导入数据asyncfunctionimportData(file){try{showLoading('正在导入数据...');constcontent=awaitreadFile(file);letdata;if(file.name.endsWith('.json')){data=JSON.parse(content);}elseif(file.name.endsWith('.csv')){data=parseCSV(content);}else{thrownewError('不支持的文件格式');}// 显示导入预览showImportPreview(data,file.name);}catch(error){showError('导入失败: '+error.message);}}// 确认导入asyncfunctionconfirmImport(data){try{constconfirmed=confirm('确定要导入这些数据吗?');if(!confirmed)return;// 导入数据if(data.diaries){awaitdb.importDiaries(data.diaries);}if(data.pets){awaitdb.importPets(data.pets);}if(data.categories){awaitdb.importCategories(data.categories);}if(data.tags){awaitdb.importTags(data.tags);}showSuccess('数据导入成功');renderImportExport();}catch(error){showError('导入失败: '+error.message);}}这些函数处理数据的导出和导入。exportAsJSON和exportAsCSV函数支持多种导出格式。importData函数自动检测文件格式并解析。
// 渲染导入导出页面asyncfunctionrenderImportExport(){consthtml=`<div class="import-export-container"> <div class="header"> <h1>导入导出</h1> </div> <div class="export-section"> <h2>导出数据</h2> <div class="export-options"> <div class="option"> <h3>导出为JSON</h3> <p>包含所有数据,可用于备份或迁移</p> <div class="buttons"> <button class="btn-primary" onclick="exportAsJSON('all')">导出全部</button> <button class="btn-secondary" onclick="exportAsJSON('diaries')">仅日记</button> <button class="btn-secondary" onclick="exportAsJSON('pets')">仅宠物</button> </div> </div> <div class="option"> <h3>导出为CSV</h3> <p>表格格式,可在Excel中打开</p> <div class="buttons"> <button class="btn-primary" onclick="exportAsCSV('diaries')">导出日记</button> <button class="btn-primary" onclick="exportAsCSV('pets')">导出宠物</button> </div> </div> </div> </div> <div class="import-section"> <h2>导入数据</h2> <div class="import-area"> <input type="file" id="import-file" accept=".json,.csv" onchange="handleFileSelect(event)"> <p>支持 JSON 和 CSV 格式</p> </div> </div> </div>`;document.getElementById('page-container').innerHTML=html;}// 处理文件选择functionhandleFileSelect(event){constfile=event.target.files[0];if(file){importData(file);}}这个渲染函数生成了导入导出界面,提供了多种导出选项和导入功能。
🔌 原生代码实现
// ImportExportPlugin.ets - 导入导出原生插件 import { fileIo } from '@kit.BasicServicesKit'; @Entry @Component struct ImportExportPlugin { // 导出文件 exportFile(fileName: string, content: string, callback: (path: string) => void): void { try { const exportPath = `/data/exports/${fileName}`; const file = fileIo.openSync(exportPath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE); fileIo.writeSync(file.fd, content); fileIo.closeSync(file.fd); callback(exportPath); } catch (error) { console.error('[ImportExportPlugin] 导出失败:', error); callback(''); } } // 选择导入文件 selectImportFile(callback: (path: string) => void): void { try { // 打开文件选择器 callback(''); } catch (error) { console.error('[ImportExportPlugin] 选择文件失败:', error); callback(''); } } build() { Column() { Web({ src: 'resource://rawfile/www/index.html', controller: new WebviewController() }) } } }这个原生插件提供了文件导出和选择功能。
Web-Native通信代码
// 导出到文件functionexportToFile(fileName,content,mimeType){returnnewPromise((resolve,reject)=>{cordova.exec((path)=>{if(path){showSuccess(`文件已导出到:${path}`);resolve(path);}else{reject(newError('导出失败'));}},(error)=>{console.error('导出失败:',error);reject(error);},'ImportExportPlugin','exportFile',[fileName,content]);});}这段代码展示了如何通过Cordova调用原生的文件导出功能。
📝 总结
导入导出模块展示了Cordova与OpenHarmony在数据交换方面的应用。在Web层,我们实现了灵活的导入导出界面和数据格式转换。在原生层,我们提供了文件操作功能。
通过多格式支持,用户可以灵活地导出和导入数据。通过数据预览,用户可以在导入前确认数据的正确性。通过Web-Native通信,我们能够充分利用OpenHarmony的文件系统能力,为用户提供完整的数据交换体验。
在实际开发中,建议实现数据验证功能,提供导入映射配置,并支持批量导入。