简体   繁体   English

将 ByteArray 下载为 pdf /处理 React 中的错误

[英]Download a by ByteArray as pdf /handle error in React

I have an api called from react.我有一个从反应中调用的 api。 it returns a pdf file.它返回一个 pdf 文件。 When i click the link as href, i can download the pdf.当我单击链接作为 href 时,我可以下载 pdf。 Now, instead of an href, i am calling a function, on clicking and from that function, i call the api.现在,我调用的是 function,而不是 href,点击并从该 function 调用 api。 But i am not able to download the file.但我无法下载该文件。 This is what i am doing:这就是我正在做的事情:

 fetch(<url>, {
        method: "GET",
        headers: {
            Accept: "application/pdf",
            "Content-Type": "application/pdf",
        },

    }).then(response => response.blob())
        .then(response => {
            var blob=response
            var reader = new window.FileReader();
            reader.readAsDataURL(blob);
            reader.onloadend = function() {
            var base64data = reader.result;
            window.open(base64data);
            }
        })
        .catch(error => {
            console.error(error);
        });

I am not able to download any file.我无法下载任何文件。 The api (written in kotlin) returns a bytearray. api(用 kotlin 编写)返回一个字节数组。 Also, if the api throws an exception instead of returning bytearray, i need to show a pop up, Any thoughts on this?另外,如果 api 抛出异常而不是返回字节数组,我需要显示一个弹出窗口,对此有什么想法吗?

You can create an invisible anchor tag somewhere in your component and use it. 您可以在组件中的某个位置创建一个不可见的锚标记并使用它。 In my solution i created an invisible anchor tag with id invisible-link 在我的解决方案中,我创建了一个ID为invisible-link的不可见锚标签

async function download(payload) {
    const response = await axios({
        url: getFileLink(payload), responseType: 'blob'
      })
    if (response.status !== 200) {
      // handle error
      return
    }
    const anchor = document.getElementById('invisible-link')
    const objectUrl = window.URL.createObjectURL(response.data)
    anchor.href = objectUrl;
    anchor.download = getDownloadFilename(response.headers)
    anchor.click()
    window.URL.revokeObjectURL(objectUrl)
}

function getDownloadFilename(headers = {}) {
  const { 'content-disposition' : disposition = '' } = headers
  const keyValue = disposition.split(';').find(e => e.includes('filename')) || ''
  const [,filename] = keyValue.split('=')
  return filename
}

here's a link of my code using this approach 这是我使用这种方法的代码的链接

To download the file you could use the file-saver npm package and use it as following: 要下载文件,您可以使用file-saver npm软件包并按以下方式使用它:

import { saveAs } from 'file-saver';

const file = new Blob([blob]);

saveAs(file, 'fileName');

To open the file in your browser: 要在浏览器中打开文件,请执行以下操作:

const file = new Blob([blob], {
  type: 'application/pdf',
});

const fileURL = URL.createObjectURL(file);

window.open(fileURL);
// Function to download the file from byte array in REACT JS   
 
const downloadPdfFromArrayBytes = (fileName = 'testFile.pdf', byteArrayResFromAPI) => {
          const arr = new Uint8Array(array);
          const blob = new Blob([arr]);
          if (navigator.msSaveBlob) {
            // IE 10+
            navigator.msSaveBlob(blob, fileName);
          } else {
            const link = document.createElement('a');
            // Browsers that support HTML5 download attribute
            if (link.download !== undefined) {
              const url = URL.createObjectURL(blob);
              link.setAttribute('href', url);
              link.setAttribute('download', fileName);
              link.style.visibility = 'hidden';
              document.body.appendChild(link);
              link.click();
              document.body.removeChild(link);
            }
          }
        };
    
    
    // Example 
    // if you have api resp in byteArray as [10,12,30,20,34,49]
    
    const fileName = 'myfileexample.pdf';
    const apiResByteArr = [10,12,30,20,34,49];
    
    downloadPdfFromArrayBytes(fileName ,apiResByteArr);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM