How do I download a pdf being passed as varbinary buffer data to front end?

Im currently working on a project using node.js. I have a table that stores all pdf files in varbinary format. I am retrieving this data from the table and creating an object named document and passing it to a ejs vew. Here are all the properties in that object document:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code> id: 2,
policy_number: 5353535,
policy_type: 'Motorcycle',
status: [ null, null, 'T-Docs Requested' ],
address: '9000 Logan st',
effective_date: null,
company: 'Progressive',
bi_liability_limits: 1000,
pd_liability_limits: null,
pip_liability_limits: null,
bi_liability_deductibles: null,
pd_liability_deductibles: null,
pip_liability_deductibles: null,
household_id: 2,
guest_deductible: 20,
guest_liability: 20,
uw_action_id: [ 53, 53 ],
request_type: 108,
assigned_to: '2',
created_on: 2024-04-24T18:43:16.543Z,
due_date: 2024-05-01T18:43:16.543Z,
created_by: '1',
policy_id: 2,
uw_action_documents_id: 35,
additional_documents: <Buffer 25 50 44 46 2d 31 2e 37 0d 0a 25 b5 b5 b5 b5 0d 0a 31 20 30 20 6f 62 6a 0d 0a 3c 3c 2f 54 79 70 65 2f 43 61 74 61 6c 6f 67 2f 50 61 67 65 73 20 32 20 ... 32052 more bytes>,
endorsements: null,
proof_of_home_ownership: null,
drivers_license: null,
fl_dl_check: null
</code>
<code> id: 2, policy_number: 5353535, policy_type: 'Motorcycle', status: [ null, null, 'T-Docs Requested' ], address: '9000 Logan st', effective_date: null, company: 'Progressive', bi_liability_limits: 1000, pd_liability_limits: null, pip_liability_limits: null, bi_liability_deductibles: null, pd_liability_deductibles: null, pip_liability_deductibles: null, household_id: 2, guest_deductible: 20, guest_liability: 20, uw_action_id: [ 53, 53 ], request_type: 108, assigned_to: '2', created_on: 2024-04-24T18:43:16.543Z, due_date: 2024-05-01T18:43:16.543Z, created_by: '1', policy_id: 2, uw_action_documents_id: 35, additional_documents: <Buffer 25 50 44 46 2d 31 2e 37 0d 0a 25 b5 b5 b5 b5 0d 0a 31 20 30 20 6f 62 6a 0d 0a 3c 3c 2f 54 79 70 65 2f 43 61 74 61 6c 6f 67 2f 50 61 67 65 73 20 32 20 ... 32052 more bytes>, endorsements: null, proof_of_home_ownership: null, drivers_license: null, fl_dl_check: null </code>
   id: 2,
   policy_number: 5353535,
   policy_type: 'Motorcycle',
   status: [ null, null, 'T-Docs Requested' ],
   address: '9000 Logan st',
   effective_date: null,
   company: 'Progressive',
   bi_liability_limits: 1000,
   pd_liability_limits: null,
   pip_liability_limits: null,
   bi_liability_deductibles: null,
   pd_liability_deductibles: null,
   pip_liability_deductibles: null,
   household_id: 2,
   guest_deductible: 20,
   guest_liability: 20,
   uw_action_id: [ 53, 53 ],
   request_type: 108,
   assigned_to: '2',
   created_on: 2024-04-24T18:43:16.543Z,
   due_date: 2024-05-01T18:43:16.543Z,
   created_by: '1',
   policy_id: 2,
   uw_action_documents_id: 35,
   additional_documents: <Buffer 25 50 44 46 2d 31 2e 37 0d 0a 25 b5 b5 b5 b5 0d 0a 31 20 30 20 6f 62 6a 0d 0a 3c 3c 2f 54 79 70 65 2f 43 61 74 61 6c 6f 67 2f 50 61 67 65 73 20 32 20 ... 32052 more bytes>,
   endorsements: null,
   proof_of_home_ownership: null,
   drivers_license: null,
   fl_dl_check: null

As you can see additional documents contains the raw binary data for the pdf. On the front end I am displaying the data as follows:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><tr >
<td><%= document.policy_number %> <br> <%= document.policy_type %></td>
<td><%= document.status %></td>
<td>UM/UIM <br> FORM</td>
<td><% if (document.additional_documents !== null) { %>
<a href="#" onclick="downloadFile('<%= document.additional_documents %>', test.pdf)">✅Additional Docs</a>
<% } else { %>
❌No additional docs
<% } %>
<br>
<%= document.endorsements !== null ? '✅Endorsements' : '❌No endorsements' %>
<br>
<%= document.proof_of_home_ownership !== null ? '✅Home Ownership' : '❌No home ownership' %>
<br>
<%= document.drivers_license !== null ? '✅DL License' : '❌No DL' %>
<br>
<%= document.fl_dl_check !== null ? '✅DL License Chcek' : '❌No DL check' %>
<br>
<%= document.created_on.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }) %></td>
<td>✍️????????️</td>
</tr> ````
</code>
<code><tr > <td><%= document.policy_number %> <br> <%= document.policy_type %></td> <td><%= document.status %></td> <td>UM/UIM <br> FORM</td> <td><% if (document.additional_documents !== null) { %> <a href="#" onclick="downloadFile('<%= document.additional_documents %>', test.pdf)">✅Additional Docs</a> <% } else { %> ❌No additional docs <% } %> <br> <%= document.endorsements !== null ? '✅Endorsements' : '❌No endorsements' %> <br> <%= document.proof_of_home_ownership !== null ? '✅Home Ownership' : '❌No home ownership' %> <br> <%= document.drivers_license !== null ? '✅DL License' : '❌No DL' %> <br> <%= document.fl_dl_check !== null ? '✅DL License Chcek' : '❌No DL check' %> <br> <%= document.created_on.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }) %></td> <td>✍️????????️</td> </tr> ```` </code>
<tr  >
    <td><%= document.policy_number %> <br> <%= document.policy_type %></td>
    <td><%= document.status %></td>
    <td>UM/UIM <br> FORM</td>
    <td><% if (document.additional_documents !== null) { %>
        <a href="#" onclick="downloadFile('<%= document.additional_documents %>', test.pdf)">✅Additional Docs</a>
      <% } else { %>
        ❌No additional docs
      <% } %>
        <br>
        <%= document.endorsements !== null ? '✅Endorsements' : '❌No endorsements' %> 
        <br>
        <%= document.proof_of_home_ownership !== null ? '✅Home Ownership' : '❌No home ownership' %> 
        <br>
        <%= document.drivers_license !== null ? '✅DL License' : '❌No DL' %> 
        <br>
        <%= document.fl_dl_check !== null ? '✅DL License Chcek' : '❌No DL check' %> 
        <br>
        <%= document.created_on.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }) %></td>
    <td>✍️????????️</td>
</tr> ````

I have two functions in script one of them is commented out because I was using it to test text files. It works perfectly fine with text files. The second function is me trying to attempt to download pdf files on the client side:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code> /* function downloadFile(fileData) {
console.log(fileData)
// Convert the varbinary data to a Blob object
const blob = new Blob([fileData], { type: 'application/octet-stream' });
// Create a URL for the Blob object
const url = window.URL.createObjectURL(blob);
// Create a link element
const link = document.createElement('a');
link.href = url;
// Set the filename for the downloaded file
link.download = 'filename.pdf';
// Append the link to the body
document.body.appendChild(link);
// Trigger the click event on the link
link.click();
// Remove the link from the body
document.body.removeChild(link);
} */
function downloadFile(base64Data, fileName) {
// Convert the base64 data to a Blob object
const byteCharacters = atob(base64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += 512) {
const slice = byteCharacters.slice(offset, offset + 512);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, { type: 'application/pdf' });
// Create a URL for the Blob object
const url = window.URL.createObjectURL(blob);
// Create a link element
const link = document.createElement('a');
link.href = url;
// Set the filename for the downloaded file
link.download = fileName;
// Append the link to the body
document.body.appendChild(link);
// Trigger the click event on the link
link.click();
// Remove the link from the body
document.body.removeChild(link);
}
</script>```
</code>
<code> /* function downloadFile(fileData) { console.log(fileData) // Convert the varbinary data to a Blob object const blob = new Blob([fileData], { type: 'application/octet-stream' }); // Create a URL for the Blob object const url = window.URL.createObjectURL(blob); // Create a link element const link = document.createElement('a'); link.href = url; // Set the filename for the downloaded file link.download = 'filename.pdf'; // Append the link to the body document.body.appendChild(link); // Trigger the click event on the link link.click(); // Remove the link from the body document.body.removeChild(link); } */ function downloadFile(base64Data, fileName) { // Convert the base64 data to a Blob object const byteCharacters = atob(base64Data); const byteArrays = []; for (let offset = 0; offset < byteCharacters.length; offset += 512) { const slice = byteCharacters.slice(offset, offset + 512); const byteNumbers = new Array(slice.length); for (let i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } const blob = new Blob(byteArrays, { type: 'application/pdf' }); // Create a URL for the Blob object const url = window.URL.createObjectURL(blob); // Create a link element const link = document.createElement('a'); link.href = url; // Set the filename for the downloaded file link.download = fileName; // Append the link to the body document.body.appendChild(link); // Trigger the click event on the link link.click(); // Remove the link from the body document.body.removeChild(link); } </script>``` </code>
  /*  function downloadFile(fileData) {
        console.log(fileData)
      // Convert the varbinary data to a Blob object
      const blob = new Blob([fileData], { type: 'application/octet-stream' });
  
      // Create a URL for the Blob object
      const url = window.URL.createObjectURL(blob);
  
      // Create a link element
      const link = document.createElement('a');
      link.href = url;
  
      // Set the filename for the downloaded file
      link.download = 'filename.pdf';
  
      // Append the link to the body
      document.body.appendChild(link);
  
      // Trigger the click event on the link
      link.click();
  
      // Remove the link from the body
      document.body.removeChild(link);
    } */
    function downloadFile(base64Data, fileName) {
    // Convert the base64 data to a Blob object
    const byteCharacters = atob(base64Data);
    const byteArrays = [];
    for (let offset = 0; offset < byteCharacters.length; offset += 512) {
        const slice = byteCharacters.slice(offset, offset + 512);
        const byteNumbers = new Array(slice.length);
        for (let i = 0; i < slice.length; i++) {
            byteNumbers[i] = slice.charCodeAt(i);
        }
        const byteArray = new Uint8Array(byteNumbers);
        byteArrays.push(byteArray);
    }
    const blob = new Blob(byteArrays, { type: 'application/pdf' });

    // Create a URL for the Blob object
    const url = window.URL.createObjectURL(blob);

    // Create a link element
    const link = document.createElement('a');
    link.href = url;

    // Set the filename for the downloaded file
    link.download = fileName;

    // Append the link to the body
    document.body.appendChild(link);

    // Trigger the click event on the link
    link.click();

    // Remove the link from the body
    document.body.removeChild(link);
}
  </script>```

When I click the additional docs button i get console.logged this error in the browser:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>```downloadFile('%PDF-1.7
%����
1 0 obj
<</Type/Catalog/Pages 2 0 R/Lang(en) /StructTreeRoot 15 0 R/MarkInfo<</Marked true>>/Metadata 27 0 R/ViewerPreferences 28 0 R>>
endobj
2 0 obj
<</Type/Pages/Count 1/Kids[ 3 0 R] >>
endobj
3 0 obj
<</Type/Page/Parent 2 0 R/Resources<</Font<</F1 5 0 R/F2 12 0 R>>/ExtGState<</GS10 10 0 R/GS11 11 0 R>>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/MediaBox[ 0 0 612 792] /Contents 4 0 R/Group<</Type/Group/S/Transparency/CS/DeviceRGB>>/Tabs/S/StructParents 0>>
endobj
4 0 obj
<</Filter/FlateDecode/Length 226>>
stream
x���Ak1�{ ���`v&q7 ,]��R�)=��S���0k+X�Kk�c�5�e�-��({�t-�n��C�tV�S
R�?��"��k|��x{@'�4J�=2����Rp�V+�9,y5ֈ�)7o��R)��ֹ����5�u�]J�/�Pť~2�s��)�?' 1�ӽV&��;G�)coXH��8���� �v���ɩ>~���� ԋ
G?x~
endstream
endobj
5 0 obj
<</Type/Font/Subtype/Type0/BaseFont/BCDEEE+Calibri/Encoding/Identity-H/DescendantFonts 6 0 R/ToUnicode 23 0 R>>
endobj
6 0 obj
[ 7 0 R] ```
</code>
<code>```downloadFile('%PDF-1.7 %���� 1 0 obj <</Type/Catalog/Pages 2 0 R/Lang(en) /StructTreeRoot 15 0 R/MarkInfo<</Marked true>>/Metadata 27 0 R/ViewerPreferences 28 0 R>> endobj 2 0 obj <</Type/Pages/Count 1/Kids[ 3 0 R] >> endobj 3 0 obj <</Type/Page/Parent 2 0 R/Resources<</Font<</F1 5 0 R/F2 12 0 R>>/ExtGState<</GS10 10 0 R/GS11 11 0 R>>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/MediaBox[ 0 0 612 792] /Contents 4 0 R/Group<</Type/Group/S/Transparency/CS/DeviceRGB>>/Tabs/S/StructParents 0>> endobj 4 0 obj <</Filter/FlateDecode/Length 226>> stream x���Ak1�{ ���`v&q7 ,]��R�)=��S���0k+X�Kk�c�5�e�-��({�t-�n��C�tV�S R�?��"��k|��x{@'�4J�=2����Rp�V+�9,y5ֈ�)7o��R)��ֹ����5�u�]J�/�Pť~2�s��)�?' 1�ӽV&��;G�)coXH��8���� �v���ɩ>~���� ԋ G?x~ endstream endobj 5 0 obj <</Type/Font/Subtype/Type0/BaseFont/BCDEEE+Calibri/Encoding/Identity-H/DescendantFonts 6 0 R/ToUnicode 23 0 R>> endobj 6 0 obj [ 7 0 R] ``` </code>
```downloadFile('%PDF-1.7
%����
1 0 obj
<</Type/Catalog/Pages 2 0 R/Lang(en) /StructTreeRoot 15 0 R/MarkInfo<</Marked true>>/Metadata 27 0 R/ViewerPreferences 28 0 R>>
endobj
2 0 obj
<</Type/Pages/Count 1/Kids[ 3 0 R] >>
endobj
3 0 obj
<</Type/Page/Parent 2 0 R/Resources<</Font<</F1 5 0 R/F2 12 0 R>>/ExtGState<</GS10 10 0 R/GS11 11 0 R>>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/MediaBox[ 0 0 612 792] /Contents 4 0 R/Group<</Type/Group/S/Transparency/CS/DeviceRGB>>/Tabs/S/StructParents 0>>
endobj
4 0 obj
<</Filter/FlateDecode/Length 226>>
stream
x���Ak1�{ ���`v&q7  ,]��R�)=��S���0k+X�Kk�c�5�e�-��({�t-�n��C�tV�S
R�?��"��k|��x{@'�4J�=2����Rp�V+�9,y5ֈ�)7o��R)��ֹ����5�u�]J�/�Pť~2�s��)�?'  1�ӽV&��;G�)coXH��8����  �v���ɩ>~���� ԋ
G?x~
endstream
endobj
5 0 obj
<</Type/Font/Subtype/Type0/BaseFont/BCDEEE+Calibri/Encoding/Identity-H/DescendantFonts 6 0 R/ToUnicode 23 0 R>>
endobj
6 0 obj
[ 7 0 R] ```

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật