HarmonyOS鸿蒙Next中base64字符串转PDF文件保存后打开显示格式损坏如何解决

HarmonyOS鸿蒙Next中base64字符串转PDF文件保存后打开显示格式损坏如何解决

import { BusinessError, systemDateTime } from "@kit.BasicServicesKit"
import { buffer } from "@kit.ArkTS"
import fs from '@ohos.file.fs';
import { picker } from "@kit.CoreFileKit";

export class FileUtil {
  static async saveBase64Image(fileName: string,base64ImageData: string, context: Context): Promise<Boolean> {
    try {
      let base64Result = FileUtil.dealBase64Str(base64ImageData)
      let file = FileUtil.createFile(context,fileName)
      let bufferImage = buffer.from(base64Result, 'base64')
      await fs.write(file.fd, bufferImage.buffer)
      fs.closeSync(file.fd)
      const documentSaveOptions = new picker.DocumentSaveOptions(); // 创建文件管理器选项实例
      documentSaveOptions.newFileNames = [fileName]; // 保存文件名(可选)
      documentSaveOptions.fileSuffixChoices = []; // 保存文件类型(可选)
      let uris: Array<string> = [];
      const documentViewPicker = new picker.DocumentViewPicker(); // 创建文件选择器实例
      documentViewPicker.save(documentSaveOptions).then((documentSaveResult: Array<string>) => {
        uris = documentSaveResult;
        console.info('documentViewPicker.save to file succeed and uris are:' + uris);
        let uri = uris[0];
        let file2 = fs.openSync(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
        let writeLen2 = fs.writeSync(file2.fd, bufferImage.buffer);
        fs.closeSync(file2);
      }).catch((err: BusinessError) => {
        console.error(`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
      })
      return Promise.resolve(true)
    } catch (e) {
      throw new Error(e)
    }
  }
  private static dealBase64Str(base64Data: string): string {
    let imageData: string
    if (base64Data.startsWith("data")) {
      const base64Split: string[] = base64Data.split(",")
      if (base64Split.length !== 2) {
        throw new Error(`ImageUtils: Illegal base64 data`)
      }
      imageData = base64Split[1].trim()
    } else {
      imageData = base64Data
    }
    return imageData
  }
  private static createFile(context: Context,fileName: string) {
    let pathDir = context.filesDir
    let filePath = `${pathDir}/${fileName}`
    let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
    return file
  }
}

更多关于HarmonyOS鸿蒙Next中base64字符串转PDF文件保存后打开显示格式损坏如何解决的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复
import { BusinessError } from "@kit.BasicServicesKit"
import { buffer } from "@kit.ArkTS"
import fs from '@ohos.file.fs';
import { picker, fileUri } from '@kit.CoreFileKit'
import { common } from '@kit.AbilityKit';
import util from '@ohos.util';
import { pdfService } from '@kit.PDFKit';

export class FileUtil {

  static async saveBase64Image(fileName: string,base64ImageData: string, context: common.UIAbilityContext) {
    try {
      let imgPath = await FileUtil.createImg(base64ImageData, context)
      await FileUtil.createFile(context, fileName, imgPath);
    } catch (e) {
      throw new Error(e)
    }
  }

  private static async createImg (base64Data: string, context: common.UIAbilityContext) {
    const imgPath = `${context.filesDir}/test.png`
    let file = fs.openSync(imgPath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
    let base64Helper = new util.Base64Helper();
    let zjl = await base64Helper.decodeSync(base64Data.split(',')[1])
    let receiveData = buffer.from(zjl)
    fs.writeSync(file.fd, receiveData.buffer);
    fs.closeSync(file.fd);
    return imgPath
  }

  private static async createFile(conText: common.UIAbilityContext, fileName: string, imgPath: string,
    url?: string) {
    const document = new picker.DocumentSaveOptions();
    document.pickerMode = picker.DocumentPickerMode.DOWNLOAD;
    new picker.DocumentViewPicker().save(document, async (err: BusinessError, result: Array<string>) => {
      if (err) {
        return;
      }
      const pathDir = new fileUri.FileUri(result[0]);
      let filePath: string;
      if (url) {
        filePath = `${url}/${fileName}.pdf`;
      } else {
        filePath = `${pathDir.path}/${fileName}.pdf`;
      }
      let pdfDocument = new pdfService.PdfDocument();
      pdfDocument.createDocument(600, 900);
      pdfDocument.insertBlankPage(1, 600, 900);
      let pdfPage: pdfService.PdfPage = pdfDocument.getPage(0);
      pdfPage.addImageObject(imgPath, 0, 0, 200, 200);
      pdfDocument.saveDocument(filePath);
      console.log(`下载成功`)
    });
  }
}

更多关于HarmonyOS鸿蒙Next中base64字符串转PDF文件保存后打开显示格式损坏如何解决的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,Base64字符串转PDF文件后格式损坏,需检查Base64解码和文件写入过程。确保使用正确的Base64解码方法,如util模块的base64 API,验证字符串完整性,避免数据截断。写入文件时,使用fs模块指定二进制模式,路径权限正确。测试PDF头标识(如%PDF)以确认文件有效性。

问题可能出在文件写入流程和文件句柄管理上。代码中两次写入操作可能导致文件内容重复或损坏:

  1. saveBase64Image 方法中,先通过 fs.write 写入临时文件,随后在 documentViewPicker.save 的回调中又用 fs.writeSync 写入同一数据到新路径,这可能导致文件内容重复或结构错误。

  2. 文件句柄关闭不一致:第一次写入后使用 fs.closeSync(file.fd),但第二次写入后错误地调用 fs.closeSync(file2)(应为 fs.closeSync(file2.fd)),可能造成资源未正确释放。

建议优化:

  • 移除重复写入逻辑,仅保留一次写入操作。
  • 确保文件句柄正确关闭,使用 fs.closeSync(fd) 而非 fs.closeSync(file)
  • 检查 base64 字符串是否包含 PDF 文件头(如 %PDF-),确保数据完整。

调整后代码应简化写入流程,避免多次操作同一数据,确保文件以二进制模式保存。

回到顶部