Dynamics CRM:在表单的 Web 资源中的文件类型字段中显示 PDF
Dynamics CRM: Display PDF from File type field in Web Resource on Form
我在文件类型字段上上传了一个 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:无法在 'Window' 上执行 'atob':要解码的字符串未正确编码。
如何在 Web 资源上正确显示来自文件类型字段的 PDF?
获取文件列内容的示例代码如下:
$.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" });
从文件列返回的内容是二进制的,而不是像您从注释中获得的 Base 64。
获得 blob 后,您可以使用 createObjectURL 方法
对于 Dynamics 365/Dataverse,您可以使用 Dataverse REST Builder 生成示例代码。
我在文件类型字段上上传了一个 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:无法在 'Window' 上执行 'atob':要解码的字符串未正确编码。
如何在 Web 资源上正确显示来自文件类型字段的 PDF?
获取文件列内容的示例代码如下:
$.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" });
从文件列返回的内容是二进制的,而不是像您从注释中获得的 Base 64。
获得 blob 后,您可以使用 createObjectURL 方法
对于 Dynamics 365/Dataverse,您可以使用 Dataverse REST Builder 生成示例代码。