【背景知识】
fs.write:将数据写入文件,使用promise异步回调。
DocumentViewPicker:文件选择器对象,用来支撑选择和保存各种格式文档。
逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。
【解决方案】
构造Excel表格对应的CSV文件数据。
使用fs.write将数据写入Excel文件。
使用DocumentViewPicker将文件保存到用户文件目录下。
示例代码如下:
typescript
import fs from '@ohos.file.fs';
import { picker } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
const DOMAIN = 0x0000;
interface Product {
name: string;
price: number;
quantity: number;
}
// 导出数据库时,此处换为查表得到的list即可
let products: Product[] = [
{ name: 'Prod,uct1', price: 10.0, quantity: 5 },
{ name: 'Pr"oduc"t2', price: 15.0, quantity: 3 }
];
@Entry
@Component
struct ExcelDemo {
convertToCSV(data: Product[]): string {
let headers = ["名称", "价格", "数量"];
let fields = ["name", "price", "quantity"];
let csvContent = headers.join("\t") + "\n";
data.forEach((product) => {
let rowData = fields.map(field => {
let value: string = Object(product)[field].toString() || ''; // 获取字段值
// 移除换行符
value = value.toString().replace(/[\n\r]/g, ' ');
// 如果值中包含逗号、引号,则用双引号包裹,并且转义双引号
if (typeof value === 'string' && (value.includes(',') || value.includes('"'))) {
let temp = value.replace(/"/g, '""');
value = `"${temp}"`;
}
return value;
});
csvContent += rowData.join("\t") + "\n";
});
return csvContent;
}
build() {
RelativeContainer() {
Button('write excel').onClick(() => {
// 定义文件路径,这里假设要保存到应用的内部存储某个目录下,可根据实际需求调整。
try {
let uris: Array<string> = [];
// 创建文件管理器选项实例
const documentSaveOptions = new picker.DocumentSaveOptions();
documentSaveOptions.newFileNames = ["Test20.xlsx"];
documentSaveOptions.fileSuffixChoices = ['文档|.xlsx', '.xlsx'];
const documentViewPicker = new picker.DocumentViewPicker(getContext(this));
// 用户选择目标文件夹,用户选择与文件类型相对应的文件夹,即可完成文件保存操作。保存成功后,返回保存文档的URI。
documentViewPicker.save(documentSaveOptions).then((documentSaveResult: Array<string>) => {
uris = documentSaveResult;
let file = fs.openSync(uris[0], fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
// 构建CSV数据
let csvData = this.convertToCSV(products);
fs.write(file.fd, csvData).then((writeLen: number) => {
hilog.info(DOMAIN, 'testTag', 'write data to file succeed and size is:', writeLen);
}).catch((err: BusinessError) => {
hilog.error(DOMAIN, 'testTag',
"write data to file failed with error message: ", err.message, ", error code: ", err.code);
}).finally(() => {
fs.closeSync(file);
});
hilog.info(DOMAIN, 'testTag', 'documentViewPicker.save to file succeed and uris are:', uris);
}).catch((err: BusinessError) => {
hilog.error(DOMAIN, 'testTag',
`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
})
} catch (e) {
hilog.error(DOMAIN, 'testTag', "documentViewPicker.save error: ", JSON.stringify(e));
}
})
}
.height('100%')
.width('100%')
}
}