HarmonyOS 鸿蒙Next中saveDocument保存PDF文件到用户公共目录下需要权限吗?

HarmonyOS 鸿蒙Next中saveDocument保存PDF文件到用户公共目录下需要权限吗? saveDocument保存PDF文件到用户公共目录下需要权限吗?

3 回复

不需要,参考demo

import { pdfService } from '@kit.PDFKit';
import { fileUri, picker } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';

@Entry
@Component
struct Index {
  @State message: string = '导出PDF文件';
  @State questions: string[] = [];
  pdfDocument = new pdfService.PdfDocument();

  aboutToAppear(): void {
    this.generateQuestions();
  }

  build() {
    RelativeContainer() {
      Button(this.message)
        .id('HelloWorld')
        .fontSize($r('app.float.page_text_font_size'))
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .onClick(() => {
          this.exportToPDF();
        })
    }
    .height('100%')
    .width('100%')
  }

  private generateQuestions() {
    this.questions = [];
    for (let i = 0; i < 50; i++) {
      const question = this.generateSingleQuestion(99);
      this.questions.push(`${question}`);
    }
  }

  private generateSingleQuestion(range: number): string {
    let num1: number, num2: number, result: number;
    num1 = Math.floor(Math.random() * (range - 1)) + 1;
    num2 = Math.floor(Math.random() * (range - num1)) + 1;
    result = num1 + num2;
    return `${num1} + ${num2} = `;
  }

  public  async exportToPDF() {
    this.generatePDFContent();
    this.saveAsPdfFile()
  }

  private generatePDFContent() {
    let isCreate = this.pdfDocument.createDocument(794, 1123);//(595, 842);
    if (isCreate) {
      console.info('documentViewPicker', `pdfDocument.getPageCount() = ${this.pdfDocument.getPageCount()}`);
      if(this.pdfDocument.getPageCount() == 0)
        this.pdfDocument.insertBlankPage(0, 794, 1123);
      let textPdfPage = this.pdfDocument.getPage(0);
      let textStyle: pdfService.TextStyle = new pdfService.TextStyle;
      let fontInfo = new pdfService.FontInfo();
      fontInfo.fontPath = '/system/fonts/HarmonyOS_Sans.ttf';
      textStyle.fontInfo = fontInfo;
      textStyle.textSize = 24;
      textStyle.textColor = 0x333333;
      textStyle.isBold = true;
      textStyle.isItalic = false;
      textPdfPage.addTextObject(`100以内加法 (50题)`,300, 1060, textStyle)
      textStyle.textSize = 18;
      let yPos = 1000
      let xPos = 50
      this.questions.forEach((question, index) => {
        textPdfPage.addTextObject(question,xPos, yPos, textStyle)
        xPos += 180
        if ((index + 1) % 4 === 0) {
          yPos -= 40;
          xPos = 50;
          if(yPos < 0)
          {
            this.pdfDocument.insertBlankPage(1, 794, 1123);
            textPdfPage = this.pdfDocument.getPage(1);
            textPdfPage.addTextObject(`100以内加法 (50题)`,300, 1060, textStyle)
            yPos = 1000
          }
        }
      });
    }
  }

  private async saveAsPdfFile() {
    const fileName = `口算练习_${Date.now()}.pdf`;
    const documentSaveOptions = new picker.DocumentSaveOptions();
    documentSaveOptions.newFileNames = [fileName]
    documentSaveOptions.fileSuffixChoices = ['.pdf'];
    let uri: string = '';
    let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
    const documentViewPicker = new picker.DocumentViewPicker(context);
    documentViewPicker.save(documentSaveOptions).then((documentSaveResult: Array<string>) => {
      uri = documentSaveResult[0];
      console.info('documentViewPicker.save succeed and uri is:' + uri);
      const savePath = new fileUri.FileUri(uri).path;
      console.info('documentViewPicker', `pdf savePath = ${savePath}`);
      let result = this.pdfDocument.saveDocument(savePath);
      console.info('documentViewPicker', `pdf 保存结果:${result}`);
    }).catch((err: BusinessError) => {
      console.error(`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
    })
  }
}

更多关于HarmonyOS 鸿蒙Next中saveDocument保存PDF文件到用户公共目录下需要权限吗?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,使用saveDocument保存PDF文件到用户公共目录(如Documents、Downloads)需要申请对应的存储权限。应用需在module.json5文件中配置ohos.permission.WRITE_USER_STORAGE权限,并在运行时动态请求用户授权。

在HarmonyOS Next中,使用saveDocument API将PDF文件保存到用户公共目录(例如Documents目录)不需要主动申请额外的文件读写权限

这是因为saveDocument API设计用于“文档类”文件的保存,其保存目标目录由系统管理(通常是Documents或下载目录的子目录),属于用户受控的公共数据区域。应用通过此API操作时,系统会代表应用在指定公共目录内创建或修改文件,因此应用自身无需声明或请求文件系统权限。

关键点说明:

  1. 权限:你的应用在module.json5配置文件中不需要声明ohos.permission.READ_MEDIAohos.permission.WRITE_MEDIA等存储权限。
  2. API使用:你只需要正确调用picker.saveDocument方法,系统会自动弹出文件选择器(FilePicker)让用户选择保存位置(默认在公共目录范围内)。用户确认后,文件即被保存。
  3. 目录访问:通过此方式保存的文件,其路径URI是受系统管理的,应用后续可以通过该URI进行访问或操作,但不能直接通过文件路径字符串访问公共目录的其他任意位置。

简单来说,saveDocument本身是一个受系统管控的安全保存通道,权限已由系统处理,开发者无需关心。

示例代码片段(ArkTS):

import picker from '@ohos.file.picker';

async function savePdfDocument() {
  try {
    const documentSaveOptions = new picker.DocumentSaveOptions();
    documentSaveOptions.newFileNames = ['MyDocument.pdf']; // 建议的文件名
    const documentPicker = new picker.DocumentViewPicker();
    const uri = await documentPicker.save(documentSaveOptions); // 系统弹出保存界面
    if (uri) {
      // 使用uri进行文件写入操作,例如将PDF数据写入该uri指向的文件
      // ... (你的文件写入逻辑)
    }
  } catch (err) {
    console.error('Failed to save document. Error: ', err);
  }
}

因此,你可以直接使用该API实现PDF保存功能,无需处理权限申请。

回到顶部