He subido un archivo PDF (tamaño 30 MB) en un campo de tipo de archivo.
Luego intento mostrar el PDF del campo en un recurso web, pero no aparece. Si trato de mostrar el mismo PDF desde la entidad de anotación, se muestra bien. Así es como obtengo los datos del campo de tipo de archivo:
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"; }El método dataURItoBlob anterior me da el siguiente error:
DOMException: no se pudo ejecutar 'atob' en 'Ventana': la cadena que se va a decodificar no está codificada correctamente.
¿Cómo mostrar correctamente el PDF desde el campo de tipo de archivo en un recurso web?
un código de muestra para obtener el contenido de una columna de archivo es el siguiente:
$.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"); } });en esta muestra puede obtener un Blob haciendo esta línea (que se comenta)
var saveFile = new Blob([fileContent], { type: "application/octet-stream" });el contenido devuelto de una columna de archivo es binario y no una base 64 como se obtiene de una anotación.
Después de obtener el blob, puede usar el método createObjectURL
Para Dynamics 365/Dataverse, puede usar Dataverse REST Builder para generar el código de muestra.