Search code examples
react-nativeexpopdf-generationblobfilereader

Problem to generate pdf from a blob in an expo app using FileSystem


I get a blob and I treat it like this:

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

  const fileReaderInstance = new FileReader();
  fileReaderInstance.readAsDataURL(blob);
  fileReaderInstance.onload = async () => {
    const fileUri = `${FileSystem.documentDirectory}file.pdf`;
    await FileSystem.writeAsStringAsync(
      fileUri,
      fileReaderInstance.result.split(',')[1],
      {
        encoding: FileSystem.EncodingType.Base64,
      }
    );
    console.log(fileUri);
    Sharing.shareAsync(fileUri);
  };

however when I generate and share the file, I can't access it and if I get its URI and search on the web it returns:

enter image description here


Solution

  • i solved my problem in this way:

    This is a func who get other data to request, do the request (generate PDF()) and treat the data and generate by received blob the buffer on (fileReaderInstance.result) who is shared in Sharing.shareAsync()

      const generatePDF = async () => {
        setAnimating(true);
        const companyReponse = await CompanyService.getCompany();
        const peopleResponse = await PeopleService.getPerson(sale.customerId);
    
        const company = companyReponse.response.company;
        const people = peopleResponse.response;
        const quote = false;
    
        const json = await SaleService.generatePDF({
          sale,
          company,
          people,
          quote,
        });
    
        if (json && json.success) {
          try {
            const fileReaderInstance = new FileReader();
            fileReaderInstance.readAsDataURL(json.data);
            fileReaderInstance.onload = async () => {
              const base64data = fileReaderInstance.result.split(',');
              const pdfBuffer = base64data[1];
    
              const path = `${FileSystem.documentDirectory}/${sale._id}.pdf`;
              await FileSystem.writeAsStringAsync(`${path}`, pdfBuffer, {
                encoding: FileSystem.EncodingType.Base64,
              });
    
              await Sharing.shareAsync(path, { mimeType: 'application/pdf' });
            };
          } catch (error) {
            Alert.alert('Erro ao gerar o PDF', error.message);
          }
        }
        setAnimating(false);
      }
    

    This is the func in SaleServicegeneratePDF who do the request to api and pass the parameters that return a blob of pdf using axios:

     generatePDF: async ({ sale, company, people, quote }) => {
        const token = await AsyncStorage.getItem('token');
        const body = { sale, company, people, quote };
        try {
          const response = await axios(`${BASE_API}/generate-sale-pdf`, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              Authorization: token,
            },
            responseType: 'blob',
            data: body,
          });
    
          return {
            success: true,
            data: response.data,
          };
        } catch (err) {
          return err.error;
        }
      },