当前位置: 首页 > news >正文

【Power Platform系列】如何在画布应用中调用工作流上传附件

在Power Apps画布应用中上传附件,比如到SharePoint文档库最典型的方式非常简单,插入一个编辑窗体,将窗体和背后的文档库绑定起来即可以快速实现。不过窗体内部的显示格式很难控制,如果要实现更为灵活的控制,就需要采用其他方式。本文实现的是在自定义界面的画布应用中选好文件点击上传按钮调用Power Automate工作流来实现附件上传,当然也可以在Patch()里直接进行上传,示例代码如下:

Patch(
  YourSharePointLibrary, 
  Defaults(YourSharePointLibrary), 
  { Title: "New Document", 
    YourColumnName: YourValue, 
    // 添加其他需要的列和值
  },
  { File: FilePicker.SelectedFile }
)

不过如果使用Power Automate可以实现更多的功能,比如将上传的文件内容通过AI识别后存储在单独的字段等则无法在Patch()里实现。

1. 构建一个简单的上传文档界面,界面如下图所示,panBulkUpload是顶层容器,下面的panNewDocument容器存储包含了上传文件的控件FileUploader(如何在画布应用里使用该控件可以参考【Power Apps系列】如何在画布应用里添加附件控件-CSDN博客)以及提示信息标签控件label1

2. 标签显示的内容为“Supported Document Type: PDF, Image; Maximal document number: 10; Allowed maximal document size: 100MB”,10和100MB来自FileUploader控件的配置,设置label1的Text属性如下即可实现

$"Supported Document Types: PDF, Image; Maximal document number: {FileUploader.MaxAttachments}; Allowed maximal document size: {FileUploader.MaxAttachmentSize}MB"

3. panBulkUpload控件的配置可以参看其代码,这里不一个个解释,留意其中的关键是garBulkUpload的Items属性设置为FileUploader.Attachments,实现了将用户上传附件的内容绑在在garBulkUpload容器

- panBulkUpload:
    Control: GroupContainer
    Variant: verticalAutoLayoutContainer
    Properties:
      DropShadow: =DropShadow.None
      Fill: =RGBA(250, 250, 250, 0.8)
      Height: =App.Height
      LayoutAlignItems: =LayoutAlignItems.Stretch
      LayoutDirection: =LayoutDirection.Vertical
      LayoutJustifyContent: =LayoutJustifyContent.Center
      LayoutMode: =LayoutMode.Auto
      Width: =App.Width
    Children:
    - panNewDocument:
        Control: GroupContainer
        Variant: verticalAutoLayoutContainer
        Properties:
          AlignInContainer: =AlignInContainer.SetByContainer
          DropShadow: =DropShadow.Bold
          Fill: =RGBA(255, 255, 255, 1)
          Height: =500
          LayoutAlignItems: =LayoutAlignItems.Stretch
          LayoutDirection: =LayoutDirection.Vertical
          LayoutJustifyContent: =LayoutJustifyContent.SpaceBetween
          LayoutMode: =LayoutMode.Auto
          PaddingBottom: =10
          PaddingLeft: =40
          PaddingRight: =40
          PaddingTop: =40
          Width: =800
          X: =(App.Width-Self.Width)/2
          Y: =(App.Height-Self.Height)/2
        Children:
        - Label1:
            Control: Label
            Properties:
              Text: |-
                =$"Supported Document Types: PDF, Image; Maximal document number: {FileUploader.MaxAttachments}; Allowed maximal document size: {FileUploader.MaxAttachmentSize}MB"
        - FileUploader:
            Control: Attachments
            Properties:
              AddAttachmentText: ="Upload file"
              Items: =[]
              MaxAttachmentSize: =100
              MaxAttachments: =10
              MaxAttachmentsText: =""
              NoAttachmentsText: ="There is no file."
              Tooltip: ="Upload documents"
              BorderColor: =Color.Red
              BorderStyle: =BorderStyle.None
              Color: =RGBA(51, 51, 51, 1)
              DisabledBorderColor: =RGBA(0, 0, 0, 0)
              FillPortions: =1
              Font: =Font.'Segoe UI'
              Height: =240
              HoverColor: =RGBA(51, 51, 51, 1)
              HoverFill: =RGBA(212, 212, 212, 1)
              ItemColor: =RGBA(0, 0, 0, 1)
              ItemFill: =RGBA(0, 120, 212, 1)
              ItemHoverColor: =RGBA(51, 51, 51, 1)
              ItemHoverFill: =RGBA(212, 212, 212, 1)
              ItemSpacing: =12
              LayoutMinHeight: =0
              NoAttachmentsColor: =RGBA(166, 166, 166, 1)
              PaddingBottom: =5
              PaddingLeft: =If(Self.DisplayMode = DisplayMode.Edit, 5, 0)
              PaddingRight: =5
              PaddingTop: =5
              PressedFill: =RGBA(0, 120, 212, 1)
              Size: =10
              Width: =Parent.Width - 60
              X: =30
              Y: =5
        - garBulkUpload:
            Control: Gallery
            Variant: BrowseLayout_Horizontal_TwoTextOneImageVariant_ver5.0
            Properties:
              Items: =FileUploader.Attachments
              BorderColor: =RGBA(166, 166, 166, 1)
              DelayItemLoading: =true
              FillPortions: =0
              FocusedBorderColor: =RGBA(0, 120, 212, 1)
              FocusedBorderThickness: =2
              Height: =80
              LoadingSpinner: =LoadingSpinner.Data
              TemplatePadding: =0
              TemplateSize: =80
              Visible: =false
            Children:
            - Title2:
                Control: Label
                Properties:
                  OnSelect: =Select(Parent)
                  Text: =ThisItem.Name
                  FontWeight: =If(ThisItem.IsSelected, FontWeight.Semibold, FontWeight.Normal)
                  Height: =Self.Size * 1.8
                  PaddingBottom: =0
                  PaddingLeft: =0
                  PaddingRight: =0
                  PaddingTop: =0
                  VerticalAlign: =VerticalAlign.Top
                  Width: =Parent.TemplateWidth - 64
                  X: =32
                  Y: =Image2.Y + Image2.Height + 16
            - Image2:
                Control: Image
                Properties:
                  OnSelect: =Select(Parent)
                  Image: =ThisItem.Value
                  Height: =296
                  ImagePosition: =ImagePosition.Fill
                  RadiusBottomLeft: =8
                  RadiusBottomRight: =8
                  RadiusTopLeft: =8
                  RadiusTopRight: =8
                  Width: =Parent.TemplateWidth - 32
                  X: =(Parent.TemplateWidth / 2) - (Self.Width / 2)
                  Y: =16
    - Container4:
        Control: GroupContainer
        Variant: horizontalAutoLayoutContainer
        Properties:
          AlignInContainer: =AlignInContainer.SetByContainer
          DropShadow: =DropShadow.None
          FillPortions: =0
          Height: =50
          LayoutAlignItems: =LayoutAlignItems.Center
          LayoutGap: =20
          LayoutJustifyContent: =LayoutJustifyContent.Center
          LayoutMode: =LayoutMode.Auto
          PaddingLeft: =40
          PaddingRight: =40
          Width: =800
        Children:
        - btnSaveNewDocument:
            Control: Classic/Button
            Properties:
              OnSelect: |-
                =UpdateContext(
                    {
                        varShowDocumentDetailPanel: false,
                        varShowSpinner:true,
                        varSpinnerMsg:"Uploading files, please wait..."
                    }
                );

                ForAll(
                    garBulkUpload.AllItems,
                    'UploadFiletoSharePoint'.Run(
                        ThisRecord.Name,
                        Substitute(
                            JSON(
                                Image2.Image,
                                JSONFormat.IncludeBinaryData
                            ),
                            """",
                            ""
                        )
                   )
                );
                Reset(FileUploader);

                UpdateContext({varShowSpinner: false});
                Notify("Successfully",NotificationType.Success,1000)
              Text: ="Upload"
              Width: =96

4. 设置Upload按钮的OnSelect的代码如下,实现文件的上传:

// 更新上下文变量的值
UpdateContext(
    {
        // 设置变量 varShowDocumentDetailPanel 为 false,隐藏文档详细信息面板
        varShowDocumentDetailPanel: false,
        // 设置变量 varShowSpinner 为 true,显示加载动画(即旋转图标)
        varShowSpinner: true,
        // 设置变量 varSpinnerMsg 为 "Uploading files, please wait...",显示加载动画时的提示信息
        varSpinnerMsg: "Uploading files, please wait..."
    }
);

// 遍历集合 garBulkUpload.AllItems 中的所有记录
ForAll(
    garBulkUpload.AllItems, // 目标集合,包含需要上传的文件信息
    // 调用自定义的流 'UploadFiletoSharePoint'
    'UploadFiletoSharePoint'.Run(
        // 传递当前记录的名称(ThisRecord.Name)作为参数
        ThisRecord.Name,
        // 将当前图片控件 Image2 的图像数据转换为 JSON 格式(包含二进制数据)
        // 并用 Substitute 函数替换掉 JSON 中的所有双引号(为了符合格式要求)
        Substitute(
            JSON(
                Image2.Image, // 从 Image2 控件获取图片
                JSONFormat.IncludeBinaryData // 指定 JSON 格式,包含二进制数据
            ),
            """", // 查找双引号
            "" // 替换为空字符串
        )
    )
);

// 重置文件上传控件 FileUploader,清空已选择的文件
Reset(FileUploader);

// 上传完成后,更新上下文变量
UpdateContext({
    // 设置变量 varShowSpinner 为 false,隐藏加载动画
    varShowSpinner: false
});

// 显示通知消息,提示用户操作成功
Notify(
    "Successfully", // 通知消息内容
    NotificationType.Success, // 通知类型(成功)
    1000 // 通知显示时间(1000 毫秒,即 1 秒)
);

5. 上面步骤通过'UploadFiletoSharePoint'.Run来调用工作流,这个工作流要在画布应用里添加进来:

6. 工作流的配置如下:

7. 上方File Content的内容做了转码处理,triggerBody() 返回的是触发器的输入数据,通常以 JSON 对象的形式存在,triggerBody()?['text_1']这个表达式从触发器的主体数据中提取名为 text_1 的属性,? 操作符用于安全地访问 JSON 对象中的属性,当属性不存在时不会抛出错误,而是返回 null。dataUriToBinary()是一个 Power Automate 中的函数,用于将 Data URI(通常是以 data:image/png;base64,... 开头的字符串)转换为二进制数据,Base64 是一种将二进制数据编码为 ASCII 字符串的方法,通常用于在需要文本存储或传输二进制数据的情况下。

@{base64(dataUriToBinary(triggerBody()?['text_1']))}

相关文章:

  • QT编程之JSON处理
  • 【VUE2】第五期——VueCli创建项目、Vuex多组件共享数据
  • 使用GitHub Actions实现Git推送自动部署到服务器
  • Diffie-Hellman协议简单介绍
  • Java入职篇(3)——Linux常用指令
  • Ubuntu上部署Flask+MySQL项目
  • 【C++】每日一练(链表的中间结点)
  • 蓝桥云客 挖矿
  • `gradio save_to_cache permission denied`
  • LeeCode题库第1456题
  • Linux应用:进程的回收
  • 2018年全国职业院校技能大赛高职组-计算机网络应用竞赛竞赛样题C卷
  • springboot+springai调用deepseek实现与大模型对话聊天
  • Log4j2漏洞攻略
  • H.264视频编解码:从原理到应用
  • 【日志队列】log日志实时写入队列,流式输出
  • 【Java 基础(人话版)】进制转换
  • 【区块链】以太坊
  • 什么是云原生?
  • 前端主题切换架构设计方案
  • 上百家单位展示AI+教育的实践与成果,上海教育博览会开幕
  • 李成钢出席中国与《数字经济伙伴关系协定》成员部级会议
  • 哈马斯官员:若实现永久停火,可交出加沙地带控制权
  • 泰山、华海、中路等山东险企综合成本率均超100%,承保业务均亏损
  • 俄谈判代表团已抵达土耳其,谈判预计在莫斯科时间10时左右开始
  • 中日东三省问题的源起——《1905年东三省事宜谈判笔记》解题