HarmonyOS鸿蒙Next中word、excel、ppt、pdf文件的下载及预览示例
HarmonyOS鸿蒙Next中word、excel、ppt、pdf文件的下载及预览示例
在 HarmonyOS NEXT 中,word,excel,ppt,pdf 实现思路
更多关于HarmonyOS鸿蒙Next中word、excel、ppt、pdf文件的下载及预览示例的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
通过HarmonyOS提供的Preview Kit(文件预览服务)实现Excel文件预览。实现思路如下:
- 使用resourceManager.getRawFdSync获取resources/rawfile目录下文件的HAP包描述符(fd)。
let srcFileDescriptor = context.resourceManager.getRawFdSync('1.xls');
- 通过fs.statSync获取文件属性,调用isFile()判断是否为普通文件。
if (!fs.statSync(srcFileDescriptor.fd).isFile()) {
console.error('Not a regular file');
return;
}
- 通过UIAbilityContext获取沙箱地址filesDir,fs.openSync打开文件,readSync/writeSync执行数据读写,操作完成后调用closeSync释放资源。
let pathDir = context.filesDir; // 通过UIAbilityContext获取沙箱地址filesDir
let filePath = pathDir + "/1.xls";
// 以同步方法打开文件或目录。若文件不存在,则创建文件/读写打开
let file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
let bufsize = 4096
let buf = new ArrayBuffer(bufsize) // 用于保存读取到的文件数据的缓冲区。
let off = 0, len = 0, readedLen = 0 // 动态调整目标文件的写入位置. 写入实际读取的字节数,累计已读取的总字节数
while (len = fs.readSync(srcFileDescriptor.fd, buf, { offset: srcFileDescriptor.offset + off, length: bufsize })) {
readedLen += len
fs.writeSync(file.fd, buf, { offset: off, length: len })
off = off + len
// 当剩余未读取的字节数小于当前分块大小时,调整bufsize为剩余大小,避免无效读取
if ((srcFileDescriptor.length - readedLen) < bufsize) {
bufsize = srcFileDescriptor.length - readedLen
}
}
// 关闭文件或目录
fs.close(file.fd)
- 通过filePreview.openPreview传入文件预览信息,打开预览窗口。 注意:①文件预览信息mimeType参数必须和文件一致,不然会无法打开。例如xls对应application/vnd.ms-excel。详细参考:文件预览支持的文件类型。 ②文件预览信息uri参数file://com.example.myapplication中com.example.myapplication为应用包名,实际使用时需要替换为当前工程项目中的应用包名。
// 文件预览信息
private fileInfo: filePreview.PreviewInfo = {
title: '1.xls', // 文件的标题名称
uri: 'file://com.example.myapplication/data/storage/el2/base/haps/entry/files/1.xls', // 文件的uri,此处com.example.myapplication为包名,请按照应用的实际包名替换
mimeType: 'application/vnd.ms-excel' // 文件(夹)的媒体资源类型
};
filePreview.openPreview(this.uiContext, this.fileInfo).then(() => {
console.info('openPreview success');
}).catch((err: BusinessError) => {
console.error('openPreview failed, err = ' + err.message);
});
完整示例代码如下:
import common from '@ohos.app.ability.common';
import fs from '@ohos.file.fs';
import { filePreview } from '@kit.PreviewKit';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct Index {
context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
uiContext: Context = this.getUIContext().getHostContext() as common.Context;
// 文件预览信息
private fileInfo: filePreview.PreviewInfo = {
title: '1.xls', // 文件的标题名称
uri: 'file://com.example.myapplication/data/storage/el2/base/haps/entry/files/1.xls', // 文件的uri,此处com.example.myapplication为包名,请按照应用的实际包名替换
mimeType: 'application/vnd.ms-excel' // 文件(夹)的媒体资源类型
};
copyFile() {
// 获取resources/rawfile目录下rawfile文件所在HAP的文件描述符(fd)
let srcFileDescriptor = this.context.resourceManager.getRawFdSync('1.xls');
// 判断文件是否是普通文件。true:是普通文件;false:不是普通文件。
if (!fs.statSync(srcFileDescriptor.fd).isFile()) {
console.error('Not a regular file');
return;
}
let pathDir = this.context.filesDir; // 通过UIAbilityContext获取沙箱地址filesDir
let filePath = pathDir + "/1.xls";
// 以同步方法打开文件或目录。若文件不存在,则创建文件/读写打开
let file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
let bufsize = 4096
let buf = new ArrayBuffer(bufsize) // 用于保存读取到的文件数据的缓冲区。
let off = 0, len = 0, readLen = 0 // 动态调整目标文件的写入位置. 写入实际读取的字节数,累计已读取的总字节数
while (len = fs.readSync(srcFileDescriptor.fd, buf, { offset: srcFileDescriptor.offset + off, length: bufsize })) {
readLen += len
fs.writeSync(file.fd, buf, { offset: off, length: len })
off = off + len
// 当剩余未读取的字节数小于当前分块大小时,调整bufsize为剩余大小,避免无效读取
if ((srcFileDescriptor.length - readLen) < bufsize) {
bufsize = srcFileDescriptor.length - readLen
}
}
// 关闭文件或目录
fs.close(file.fd)
}
build() {
Row() {
Column() {
Button('传到沙箱')
.onClick(() => {
this.copyFile()
})
.margin({ bottom: 10 })
Button('预览文件')
.onClick(() => {
filePreview.openPreview(this.uiContext, this.fileInfo).then(() => {
console.info('openPreview success');
}).catch((err: BusinessError) => {
console.error('openPreview failed, err = ' + err.message);
});
})
}
.width('100%')
}
.height('100%')
}
}
文件下载预览,具体参考:文件下载预览-关键场景示例-综合办公类行业实践-行业实践 - 华为HarmonyOS开发者
文件下载基础版本 重复下载相同文件会出错
import { qq } from '../common/data';
import { request } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';
@Entry
@Component
struct Index {
@State progress: number = 0;
build() {
Column() {
Button("下载文件")
.onClick(() => {
request.downloadFile(getContext(this),{
url: qq,
background: true,
}).then((task:request.DownloadTask)=>{
task.on("progress",(receivedSize: number, totalSize: number)=>{
this.progress = Math.ceil((receivedSize / totalSize) * 100);
})
task.on("complete",()=>{
this.progress = 100
promptAction.showToast({
message: "下载完成",
})
})
})
})
Progress({ value: this.progress, total: 100, type: ProgressType.Capsule })
.width(100)
.height(50)
.style({
borderColor: Color.Blue,
borderWidth: 1,
content: this.progress + '%',
font: { size: 13, style: FontStyle.Normal },
fontColor: Color.Gray,
enableScanEffect: false,
showDefaultPercentage: true
})
.privacySensitive(true)
.margin({ top: 30 })
}
.height('100%')
.width('100%')
}
}
文件下载(断点续传)+多线程+通知 使用。request.agent.
import { qq } from '../common/data';
import { request } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';
@Entry
@Component
struct Index {
@State progress: number = 0;
taskId:string = ""
async aboutToAppear(): Promise<void> {
let task = await request.agent.create(getContext(this),{
action:request.agent.Action.DOWNLOAD,
url: qq,
//支持复写
overwrite:true,
//通知
gauge:true,
// //保存文件目录
// saveas:getContext(this).cacheDir
})
task.on("progress",(progress:request.agent.Progress)=>{
//sizes是多个文件的大小
this.progress = Math.ceil(progress.processed * 100 / progress.sizes[0])
})
task.on("completed",()=>{
promptAction.showToast({
message:"下载完成"
})
})
this.taskId = task.tid
}
build() {
Column() {
Button("下载文件")
.onClick(() => {
promptAction.showToast({
message:"开始下载"
})
request.agent.getTask(getContext(this),this.taskId).then((task:request.agent.Task)=>{
task.start()
})
})
Button("暂停")
.onClick(() => {
promptAction.showToast({
message:"暂停下载"
})
request.agent.getTask(getContext(this),this.taskId).then((task:request.agent.Task)=>{
task.pause()
})
})
Button("继续")
.onClick(() => {
promptAction.showToast({
message:"继续下载"
})
request.agent.getTask(getContext(this),this.taskId).then((task:request.agent.Task)=>{
task.resume()
})
})
Progress({ value: this.progress, total: 100, type: ProgressType.Capsule })
.width(100)
.height(50)
.style({
borderColor: Color.Blue,
borderWidth: 1,
content: this.progress + '%',
font: { size: 13, style: FontStyle.Normal },
fontColor: Color.Gray,
enableScanEffect: false,
showDefaultPercentage: true
})
.privacySensitive(true)
.margin({ top: 30 })
}
.height('100%')
.width('100%')
}
}
Preview Kit 预览
PDF常见的预览与下载一般都用这个:PDF下载和预览-行业常见问题-运动健康类行业实践-行业实践 - 华为HarmonyOS开发者
其他的文件可以引导用户使用WPS打开
我都是直接跳转到浏览器,然后用户在随意用WPS等工具打开。
HarmonyOS Next中,文件下载可通过网络模块实现,预览使用系统内置能力。下载示例:调用@ohos.net.http
发起请求,获取文件流后通过@ohos.file.fs
写入应用沙箱路径。预览通过want
隐式启动系统文件查看器,指定文件URI和MIME类型(如application/pdf)。系统自动匹配可用应用打开文档,无需额外处理格式兼容。
在HarmonyOS Next中,处理Word、Excel、PPT和PDF文件的下载与预览可以通过以下方式实现:
-
文件下载:
使用@ohos.net.http
模块发起网络请求获取文件数据,结合@ohos.file.fs
将数据写入本地存储路径。示例代码:// 发起下载请求并保存文件 const filePath = '本地存储路径/文件名.docx'; // 实现下载逻辑
-
文件预览:
对于PDF,可使用@ohos.file.picker
选择文件后通过系统能力打开;Office文件需依赖第三方库或转换为PDF预览。目前HarmonyOS Next原生支持PDF预览,但Office格式需集成适配库。
注意:实际开发中需处理权限申请(如网络和存储访问)及文件类型匹配。推荐使用ArkTS编写,确保兼容HarmonyOS Next的API版本。