【问题标题】:Dynamics CRM: Display PDF from File type field in Web Resource on FormDynamics CRM:从表单上 Web 资源中的文件类型字段显示 PDF
【发布时间】:2021-12-27 08:26:56
【问题描述】:

我在文件类型字段上上传了一个 PDF 文件(大小 30MB)。

然后,我尝试在 Web 资源上显示该字段中的 PDF,但它没有显示。如果我尝试从注释实体显示相同的 PDF,它显示得很好。这就是我从文件类型字段中获取数据的方式:

            var startBytes = 0;
            var req;
            var increment = 4194304;
            var clientUrl = Xrm.Utility.getGlobalContext().getClientUrl();
            var url = clientUrl + "/api/data/v9.1/my_entity(" + recId + ")/my_fields?size=full";

            while (startBytes <= fileSize) {
                var result = await makeRequest("GET", url, startBytes, increment);
                req = result.target;
                if (req.status === 206) {
                    finalContent += JSON.parse(req.responseText).value;
                    startBytes += increment;
                    if (fileSize === 0) {
                        fileSize = req.getResponseHeader("x-ms-file-size");
                        fileName = req.getResponseHeader("x-ms-file-name");
                    }
                }
                else if (req.status === 404) {
                    break;
                }
            }

        if (fileBodyAndMimeType[1] === "pdf") {
            var newSrc = "data:application/pdf;base64," + finalContent;
            const blob = dataURItoBlob(newSrc);
            var temp_url = window.URL.createObjectURL(blob);
            $("#myframe").attr("data", temp_url);
            document.getElementById("myImage").style.display = "none";
        }

上面的 dataURItoBlob 方法给了我以下错误:

DOMException: Failed to execute 'atob' on 'Window': 要解码的字符串编码不正确。

如何在网络资源上正确显示来自文件类型字段的 PDF?

【问题讨论】:

    标签: javascript dynamics-crm webresource


    【解决方案1】:

    获取文件列内容的示例代码如下:

    $.ajax({
        type: "GET",
        contentType: "application/json; charset=utf-8",
        xhr: function() { var xhr = new XMLHttpRequest(); xhr.responseType = "blob"; return xhr; },
        url: Xrm.Utility.getGlobalContext().getClientUrl() + "/api/data/v9.1/sample_customtables(2fb4d8e0-4ac9-f27a-939e-e52621aae0d8)/sample_file/$value",
        beforeSend: function (req) {
            req.setRequestHeader("OData-MaxVersion", "4.0");
            req.setRequestHeader("OData-Version", "4.0");
            req.setRequestHeader("Accept", "application/json");
        },
        async: true,
        success: function (data, textStatus, xhr) {
            var fileContent = data;
            var fileName = "file.bin"; // default name
            
            // NOTE: the following code decodes the file name from the header
            var contentDisposition = xhr.getResponseHeader("content-disposition");
            try {
                var strToCheck = "filename=";
                var mimeEncodingCheck = "\"=?utf-8?B?";
                if (contentDisposition.indexOf(strToCheck) > 0) {
                    var parseFileName = contentDisposition.substring(contentDisposition.indexOf(strToCheck) + strToCheck.length);
                    if (parseFileName.indexOf(mimeEncodingCheck) === -1) { fileName = parseFileName; }
                    else {
                        var parseFileNameBase64 = parseFileName.substring(parseFileName.indexOf(mimeEncodingCheck) + mimeEncodingCheck.length, parseFileName.length - 3);
                        fileName = decodeURIComponent(atob(parseFileNameBase64).split("").map(function (c) { return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2); }).join(""));
                    }
                }
            } catch {}
    
            console.log("File retrieved. Name: " + fileName);
    
            // NOTE: Uncomment the following lines to download the file
            // var saveFile = new Blob([fileContent], { type: "application/octet-stream" });
            // var customLink = document.createElement("a");
            // customLink.href = URL.createObjectURL(saveFile);
            // customLink.download = fileName;
            // customLink.click();
        },
        error: function (xhr, textStatus, errorThrown) {
            console.log("Error retrieving the File");
        }
    });
    

    在此示例中,您可以通过执行此行(已注释)获得 Blob

    var saveFile = new Blob([fileContent], { type: "application/octet-stream" });
    

    从 File 列返回的内容是二进制的,而不是像从注释中获得的 Base 64。

    获得 blob 后可以使用 createObjectURL 方法

    对于 Dynamics 365/Dataverse,您可以使用 Dataverse REST Builder 生成示例代码。

    【讨论】:

    • 您好 Guido,感谢您的回答。我实现了您的代码,但出现以下错误:JqueryJS:12 Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': 只有对象的 'responseType' 为 '' 或 'text' 时才能访问该值(是“blob”)。
    • @3iL 错误并不简单,因为我发布的代码中不存在 responseText。尝试使用 Dataverse REST Builder(如果可能,使用托管解决方案版本)并尝试使用“管理文件数据”请求类型检索文件。 (使用 XrmToolBox 版本,您可以检索文件但不解析名称)
    • Dataverse REST Builder 中的 XMLHttpRequest 为我工作!谢谢。
    • @3iL 感谢您的反馈,“管理文件数据”请求非常复杂,我将在下一个版本中改进它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多