导入导出 - Cordova 与 OpenHarmony 混合开发实战
本文介绍了MovieTracker应用的导入导出模块功能,支持JSON和CSV格式的数据交换。该模块包含导出数据(支持JSON/CSV格式)、导入数据(验证有效性)等功能,通过Cordova框架与OpenHarmony原生能力实现。代码示例展示了HTML界面结构和JavaScript实现逻辑,包括文件读取、格式转换、数据验证等关键步骤。模块提高了数据的可移植性,便于用户在不同设备间迁移应用数据。
欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

📌 模块概述
导入导出模块是MovieTracker应用中用于数据交换的功能。用户可以将应用数据导出为JSON或CSV格式,也可以从这些格式的文件导入数据。导入导出功能支持与其他应用或设备的数据交换,提高了数据的可移植性。
该模块的主要功能包括:导出为JSON、导出为CSV、导入JSON、导入CSV、数据验证等。通过Cordova框架与OpenHarmony原生能力的结合,实现了完整的数据导入导出功能。
导入导出需要处理不同格式的数据转换,同时需要验证导入数据的有效性。
🔗 完整流程
第一步:数据导出
用户可以选择导出格式(JSON或CSV)和导出范围(所有数据或特定数据)。导出过程包括数据序列化、格式转换、文件生成等步骤。
导出完成后文件保存到用户指定的位置,用户可以通过文件管理器访问导出的文件。
第二步:数据导入
用户可以选择要导入的文件。导入过程包括文件读取、格式识别、数据验证、数据导入等步骤。
导入前需要验证数据的有效性,确保导入的数据不会破坏现有数据。导入时可以选择覆盖或合并现有数据。
第三步:数据验证与处理
导入数据前需要进行验证,检查数据的完整性和有效性。验证失败时需要显示详细的错误信息,告知用户具体的问题。
同时需要处理数据冲突,如重复的影片等。
🔧 Web代码实现
导入导出HTML结构
<div id="import-export-page" class="page">
<div class="page-header">
<h2>导入导出</h2>
</div>
<div class="import-export-container">
<div class="export-section">
<h3>导出数据</h3>
<div class="form-group">
<label>导出格式:</label>
<select id="export-format" class="form-select">
<option value="json">JSON 格式</option>
<option value="csv">CSV 格式</option>
</select>
</div>
<button class="btn btn-primary" onclick="exportData()">📥 导出</button>
</div>
<div class="import-section">
<h3>导入数据</h3>
<input type="file" id="import-file" accept=".json,.csv" class="form-input">
<div class="form-group">
<label>导入方式:</label>
<select id="import-mode" class="form-select">
<option value="merge">合并</option>
<option value="replace">覆盖</option>
</select>
</div>
<button class="btn btn-primary" onclick="importData()">📤 导入</button>
</div>
</div>
</div>
导入导出实现
async function exportData() {
try {
const format = document.getElementById('export-format').value;
const allMovies = await db.getAllMovies();
let content, filename;
if (format === 'json') {
content = JSON.stringify(allMovies, null, 2);
filename = `movies_${Date.now()}.json`;
} else {
content = convertToCSV(allMovies);
filename = `movies_${Date.now()}.csv`;
}
downloadFile(content, filename);
showSuccess('数据已导出');
} catch (error) {
console.error('导出失败:', error);
showError('导出失败');
}
}
function convertToCSV(movies) {
const headers = ['标题', '导演', '年份', '评分', '分类', '状态'];
const rows = movies.map(m => [
m.title,
m.director,
m.year,
m.rating || '',
m.category || '',
m.status
]);
const csv = [headers, ...rows]
.map(row => row.map(cell => `"${cell}"`).join(','))
.join('\n');
return csv;
}
function downloadFile(content, filename) {
const blob = new Blob([content], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.click();
URL.revokeObjectURL(url);
}
async function importData() {
const fileInput = document.getElementById('import-file');
const file = fileInput.files[0];
if (!file) {
showError('请选择文件');
return;
}
try {
const content = await readFile(file);
const mode = document.getElementById('import-mode').value;
let data;
if (file.name.endsWith('.json')) {
data = JSON.parse(content);
} else if (file.name.endsWith('.csv')) {
data = parseCSV(content);
} else {
showError('不支持的文件格式');
return;
}
// 验证数据
const errors = validateImportData(data);
if (errors.length > 0) {
showError('数据验证失败:\n' + errors.join('\n'));
return;
}
// 导入数据
if (mode === 'replace') {
await db.clearAllMovies();
}
for (let movie of data) {
await db.addMovie(movie);
}
showSuccess('数据已导入');
fileInput.value = '';
} catch (error) {
console.error('导入失败:', error);
showError('导入失败: ' + error.message);
}
}
function readFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = e => resolve(e.target.result);
reader.onerror = reject;
reader.readAsText(file);
});
}
function parseCSV(content) {
const lines = content.split('\n');
const headers = lines[0].split(',').map(h => h.replace(/"/g, ''));
const data = [];
for (let i = 1; i < lines.length; i++) {
if (!lines[i].trim()) continue;
const values = lines[i].split(',').map(v => v.replace(/"/g, ''));
const movie = {
title: values[0],
director: values[1],
year: parseInt(values[2]),
rating: values[3] ? parseFloat(values[3]) : null,
category: values[4],
status: values[5]
};
data.push(movie);
}
return data;
}
function validateImportData(data) {
const errors = [];
if (!Array.isArray(data)) {
errors.push('数据格式不正确');
return errors;
}
data.forEach((movie, index) => {
if (!movie.title) errors.push(`第 ${index + 1} 行: 标题不能为空`);
if (!movie.director) errors.push(`第 ${index + 1} 行: 导演不能为空`);
if (!movie.year) errors.push(`第 ${index + 1} 行: 年份不能为空`);
});
return errors;
}
🔌 OpenHarmony原生代码
导入导出插件
// ImportExportPlugin.ets
import { webview } from '@kit.ArkWeb';
import { common } from '@kit.AbilityKit';
import { fileIo } from '@kit.CoreFileKit';
export class ImportExportPlugin {
private context: common.UIAbilityContext;
constructor(context: common.UIAbilityContext) {
this.context = context;
}
public registerImportExport(controller: webview.WebviewController): void {
controller.registerJavaScriptProxy({
object: new ImportExportBridge(this.context),
name: 'importExportNative',
methodList: ['exportToFile', 'importFromFile']
});
}
}
导入导出实现
export class ImportExportBridge {
private context: common.UIAbilityContext;
constructor(context: common.UIAbilityContext) {
this.context = context;
}
public exportToFile(dataJson: string, format: string): string {
try {
const timestamp = Date.now();
const filename = `movies_${timestamp}.${format}`;
const filepath = `${this.context.filesDir}/${filename}`;
const file = fileIo.openSync(filepath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE);
fileIo.writeSync(file.fd, dataJson);
fileIo.closeSync(file.fd);
return JSON.stringify({
success: true,
filepath: filepath,
filename: filename
});
} catch (error) {
return JSON.stringify({
success: false,
error: error.message
});
}
}
public importFromFile(filepath: string): string {
try {
const content = fileIo.readTextSync(filepath);
const data = JSON.parse(content);
return JSON.stringify({
success: true,
data: data,
count: Array.isArray(data) ? data.length : 1
});
} catch (error) {
return JSON.stringify({
success: false,
error: error.message
});
}
}
}
📝 总结
导入导出模块展示了Cordova与OpenHarmony混合开发中的数据交换功能。通过Web层提供导入导出界面,同时利用OpenHarmony原生能力进行文件操作。
在实现这个模块时,需要注意数据格式的转换、数据验证的完整性、以及用户体验的流畅性。通过合理的架构设计,可以构建出高效、易用的导入导出功能。
更多推荐
所有评论(0)