简体   繁体   English

你如何在 Svelte/JavaScript 中渲染 PDF 文件?

[英]How do you render PDF file in Svelte/JavaScript?

I am working on a college project.我正在做一个大学项目。

Can someone help me understand how best I could render a PDF file on the client side (svelte + javascript + UIKit)?有人可以帮助我了解如何最好地在客户端呈现 PDF 文件(svelte + javascript + UIKit)吗? I managed to fetch the URL (http://localhost:4000/api/v1/document/14), parse JSON to get the document.Body data and log it to the developer console.我设法获取了 URL (http://localhost:4000/api/v1/document/14),解析 JSON 以获取 document.Body 数据并将其记录到开发人员控制台。 I have looked at several sources online and have not been able to render the file on the client side.我在网上查看了几个来源,但无法在客户端呈现文件。

I have a Go API backend that reads file data based on the path referenced to it in the DB.我有一个 Go API 后端,它根据数据库中引用的路径读取文件数据。 I then populate the Body field with file content in bytes.然后,我使用以字节为单位的文件内容填充Body字段。

// GetDocument - retrieves documents by their ID from the database
func GetDocument(ID uint) (Document, error) {
    ....code here..........
    // read the filename and return the contents (bytes).
    body, err := os.ReadFile(document.Path)
    if err != nil {
        glog.Errorf("unable to read file: %v", err)
    }
    document.Body = string(body)

    return document, nil
}

I have confirmed the JSON response body contains file data using postman.我已经确认 JSON 响应正文包含使用 postman 的文件数据。

{
    "ID": 14,
    "CreatedAt": "2022-02-23T12:08:46.313118Z",
    "UpdatedAt": "2022-02-23T12:08:46.313118Z",
    "DeletedAt": null,
    "path": "/app/docs/sample.pdf",
    "title": "sample.pdf",
    "version": "1.0",
    "author": "",
    "body":"%PDF-1.4\n%äüöß\n2 0 obj\n<</Length 3 0 R/Filter/FlateDecode>>\nstream\nx��M�,7�޿�΁��䏲ah虞\t��݁=���͆���撿Y�e��^w^��˲$�[�2g��8�2���O��Stp����9����'�����=�p�'�'ᜦ�����7����\tM�f7O?O�x�\t�����\fk��&\\�����?^��I�ʏ�����q�~�pvD5DC�U��q(�lb�c^��+�z6���ъ�ѻ\t`\fЊ�э�^��vf<�I�2�����S,��\tad�i\"\t����Q����ĕQ\"��92I�Ї��28��$Y����\r^�H����\u000b>!���g�,bh�D���Z~^�f�W�>_\n>��~n�Ut��� ������\tGD��1���U���+�\f�艗���`=�^�\r?�̥<�i~�lV��z��z�ጽv�^��m��ȼ�^�V&���/������k��.�W��1}��m�u����Y�ҏ�E������1�:��\f�%9[t���{����^;ţۺ=�'ŗ��\fIM�����{�����;*h��\t,�T�L��ܫ�ۖ�������s��-R�d�M��4�Ǚ�]���7Nۮ)\/���TUDŽժ���D�>>�_��V��\n��K�^R�٨���\u000b�fe��~��MOB�۟=a�ˎ~:��:�l��5�\r�)��|�*0o�SpG���=�ufL9c��p���ʓ�{�.fp����j��LM��\\r���K>5��D��I�O�jӯ�-s��3�̞P)`��}�ŏO?�X�qL[�+4�G��V���b�_�����|y�$�̾yZ��[���e�[�����/�dOpP\bF\r$��&���&esU�����f�q8��?\nendstream\nendobj\n\n37 0 obj\n34718\nendobj\n\n38 0 obj\n<</Type/FontDescriptor/FontName/Symbol\n/Flags 4\n/FontBBox[-180 -293 1089 1010]/ItalicAngle 0\n/Ascent 1010\n/Descent -293\n/CapHeight 1010\n/StemV 80\n/FontFile 36 0 R\n>>\nendobj\n\n39 0 obj\n<</Length 995/Filter/FlateDecode>>\nstream\nx�]��n\"9��=OQ˞E\u000b�oDB�|����&3@��A���E޾��gn�Hr\bU�w\\V���XO����������t����Ǵ����xZܭ��q�}���o��b9����~�O/��v��}���:}_���<��X�:��xz������O�˷�m<]����a8�/�8?�.����e����a��x��:���|^�a�?�Aٟ��e����u\\lW��a���b<~��n������_�i�]�kW��9ߑ���䵲!eK�ʎ��=�+rPސ7���{�H�ʉ��39+rQ�����sí�o�7�������7��F~���o��\r~#��o�7�������7��F~���o��\r~#��o�����������[�V~���o�[�-~+��o�����������[�V~���o�[�-~+����w�������w�;�N~�����;�~'����w�������w�;�N~�����;�~'���M�����{�^~�����{�=~���������������{�^~�����{�=~/����������Z��?���� ������?���A��?���� ������?b�2G�Q��9�1G�#����h�7����/�H��2�2Qe\"e��D�D����*)U&R&�L�LT�H��2�2���aD=�D��b�bI�Œ�%�%KKz\t�?�O�'�I��?ɟ�'��$Ÿ�O�����������ğ������?���g�Y��?˟�g�3���2���2�,Ɵ������?���g�?k�3럵����/��E����h�bȚ�X��*������/��E���q�3>~��_�/������/�W�U����_�</�[\rY�VKּ�U��e��,Cݐe��dj$wC�oZ7dr7���@e�4�����\rs���g���=ӯo���\r3sӚ7�Mk�07uo���7�M��ͬ��fV�v3�o���_\": ����k�L�|��Ǽ~��9�x�9\t^�����GM�\nendstream\nendobj\n\n40 0 obj\n<</Type/Font/Subtype/Type1/BaseFont/Symbol\n/ToUnicode 39 0 R\n/FirstChar 0 /LastChar 255\n/Widths[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n250 333 713 500 549 833 778 439 333 333 500 549 250 549 250 278\n500 500 500 500 500 500 500 500 500 500 278 278 549 549 549 444\n549 722 667 722 612 611 763 603 722 333 631 722 686 889 722 722\n768 741 556 592 611 690 439 768 645 795 611 333 863 333 658 500\n0 631 549 549 494 439 521 411 603 329 603 549 549 576 521 549\n549 521 549 603 439 576 713 686 493 686 494 480 200 480 549 0\n0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n762 620 247 549 167 713 500 753 753 753 753 1042 987 603 987 603\n400 549 411 549 549 713 494 460 549 549 549 549 1000 0 0 658\n823 686 795 987 768 768 823 768 768 713 713 713 713 713 713 713\n768 713 0 0 0 823 549 250 713 603 603 1042 987 603 987 603\n494 329 0 0 0 713 0 0 0 0 0 0 0 0 0 0\n0 329 274 686 0 686 0 0 0 0 0 0 0 0 0 0\n]\n/FontDescriptor 38 0 R>>\nendobj\n\n41 0 obj\n<</F1 35 0 R/F2 20 0 R/F3 30 0 R/F4 40 0 R/F5 25 0 R\n>>\nendobj\n\n42 0 obj\n<</Font 41 0 R\n/XObject<</Im13 13 0 R>>\n/ProcSet[/PDF/Text/ImageC/ImageI/ImageB]\n>>\nendobj\n\n1 0 obj\n<</Type/Page/Parent 15 0 R/Resources 42 0 R/MediaBox[0 0 595 842]/Annots[\n14 0 R ]\n/Group<</S/Transparency/CS/DeviceRGB/I true>>/Contents 2 0 R>>\nendobj\n\n4 0 obj\n<</Type/Page/Parent 15 0 R/Resources 42 0 R/MediaBox[0 0 595 842]/Group<</S/Transparency/CS/DeviceRGB/I true>>/Contents 5 0 R>>\nendobj\n\n7 0 obj\n<</Type/Page/Parent 15 0 R/Resources 42 0 R/MediaBox[0 0 595 842]/Group<</S/Transparency/CS/DeviceRGB/I true>>/Contents 8 0 R>>\nendobj\n\n10 0 obj\n<</Type/Page/Parent 15 0 R/Resources 42 0 R/MediaBox[0 0 595 842]/Group<</S/Transparency/CS/DeviceRGB/I true>>/Contents 11 0 R>>\nendobj\n\n43 0 obj\n<</Count 5/First 44 0 R/Last 46 0 R\n>>\nendobj\n\n44 0 obj\n<</Count 0/Title<FEFF004C006F00720065006D00200069007000730075006D00200064006F006C006F0072002000730069007400200061006D00650074002C00200063006F006E00730065006300740065007400750072002000610064006900700069007300630069006E006700200065006C00690074002E0020004E0075006E00630020006100630020006600610075006300690062007500730020006F00640069006F002E>\n/Dest[1 0 R/XYZ 74.7 697.1 0]/Parent 43 0 R/Next 45 0 R>>\nendobj\n\n45 0 obj\n<</Count 0/Title<FEFF00430072006100730020006600720069006E00670069006C006C006100200069007000730075006D0020006D00610067006E0061002C00200069006E0020006600720069006E00670069006C006C0061002000640075006900200063006F006D006D006F0064006F00200061002E>\n/Dest[4 0 R/XYZ 74.7 537.2 0]/Parent 43 0 R/Prev 44 0 R/Next 46 0 R>>\nendobj\n\n46 0 obj\n<</Count 2/First 47 0 R/Last 48 0 R\n/Title<FEFF004C006F00720065006D00200069007000730075006D00200064006F006C006F0072002000730069007400200061006D00650074002C00200063006F006E00730065006300740065007400750072002000610064006900700069007300630069006E006700200065006C00690074002E>\n/Dest[7 0 R/XYZ 74.7 785.3 0]/Parent 43 0 R/Prev 45 0 R>>\nendobj\n\n47 0 obj\n<</Count 0/Title<FEFF004D0061006500630065006E006100730020006D006100750072006900730020006C00650063007400750073002C0020006C006F0062006F00720074006900730020006500740020007000750072007500730020006D00610074007400690073002C00200062006C0061006E006400690074002000640069006300740075006D002000740065006C006C00750073002E>\n/Dest[7 0 R/XYZ 74.7 558.4 0]/Parent 46 0 R/Next 48 0 R>>\nendobj\n\n48 0 obj\n<</Count 0/Title<FEFF0049006E00200065006C0065006900660065006E0064002000760065006C006900740020007600690074006100650020006C0069006200650072006F00200073006F006C006C0069006300690074007500640069006E00200065007500690073006D006F0064002E>\n/Dest[7 0 R/XYZ 74.7 321.4 0]/Parent 46 0 R/Prev 47 0 R>>\nendobj\n\n15 0 obj\n<</Type/Pages\n/Resources 42 0 R\n/MediaBox[ 0 0 595 842 ]\n/Kids[ 1 0 R 4 0 R 7 0 R 10 0 R ]\n/Count 4>>\nendobj\n\n14 0 obj\n<</Type/Annot/Subtype/Link/Border[0 0 0]/Rect[92 355.7 189.9 371.4]/A<</Type/Action/S/URI/URI(https://products.office.com/en-us/word)>>\n>>\nendobj\n\n49 0 obj\n<</Type/Catalog/Pages 15 0 R\n/OpenAction[1 0 R /XYZ null null 0]\n/Outlines 43 0 R\n/Lang(en-US)\n>>\nendobj\n\n50 0 obj\n<</Creator<FEFF005700720069007400650072>\n/Producer<FEFF004C0069006200720065004F0066006600690063006500200034002E0032>\n/CreationDate(D:20170816144413+02'00')>>\nendobj\n\nxref\n0 51\n0000000000 65535 f \n0000138560 00000 n \n0000000019 00000 n \n0000002806 00000 n \n0000138722 00000 n \n0000002827 00000 n \n0000006544 00000 n \n0000138866 00000 n \n0000006565 00000 n \n0000010276 00000 n \n0000139010 00000 n \n0000010297 00000 n \n0000010502 00000 n \n0000010523 00000 n \n0000141115 00000 n \n0000140996 00000 n \n0000061445 00000 n \n0000073054 00000 n \n0000073077 00000 n \n0000073272 00000 n \n0000073769 00000 n \n0000074103 00000 n \n0000081507 00000 n \n0000081529 00000 n \n0000081725 00000 n \n0000082091 00000 n \n0000082317 00000 n \n0000091907 00000 n \n0000091929 00000 n \n0000092129 00000 n \n0000092531 00000 n \n0000092791 00000 n \n0000100402 00000 n \n0000100424 00000 n \n0000100627 00000 n \n0000101037 00000 n \n0000101308 00000 n \n0000136140 00000 n \n0000136163 00000 n \n0000136346 00000 n \n0000137411 00000 n \n0000138386 00000 n \n0000138459 00000 n \n0000139156 00000 n \n0000139212 00000 n \n0000139626 00000 n \n0000139956 00000 n \n0000140304 00000 n \n0000140690 00000 n \n0000141271 00000 n \n0000141386 00000 n \ntrailer\n<</Size 51/Root 49 0 R\n/Info 50 0 R\n/ID [ <F6E9CC2B383667A7FACE2422EADAAE69>\n<F6E9CC2B383667A7FACE2422EADAAE69> ]\n/DocChecksum /6555A4DFC7A04D784A4A9B0AF82889CB\n>>\nstartxref\n141561\n%%EOF\n"
}

FileViewer.svelte文件查看器.svelte

<script>
  import {onMount} from 'svelte'
  import {navBar, mainBar, subTitle, title} from "../stores";

  title.set("Field Service Engineering Solutions");
  subTitle.set("Document Viewer");
  navBar.set({
    bar: mainBar
  });



  const url = `http://localhost:4000/api/v1/document/14`;

  let responseObject;

  onMount(async () => {
    const response = await fetch(url)
    .then(response => response.json())
    .then(response => {
      console.log(response);
    })
    .catch(error => {
      responseObject = {};
      console.log(error);
    })
  })

</script>

<div class="uk-child-width-expand@s uk-text-center" uk-grid>
  <div class="uk-card uk-card-default uk-card-body">
    <h1>hello</h1>
  </div>
</div>

screen capture of application console log应用程序控制台日志的屏幕截图

I have found a solution to my question in other stack overflow posts.我在其他堆栈溢出帖子中找到了我的问题的解决方案。 For anyone with a similar issue please refer to the links below.对于任何有类似问题的人,请参阅下面的链接。

Once I changed how the file was retrieved from the Db on the backend, I could call that endpoint on the front-end.一旦我更改了从后端 Db 检索文件的方式,我就可以在前端调用该端点。 This renders a PDF file in a new tab.这会在新选项卡中呈现一个 PDF 文件。

<td><a href="http://localhost:4000/api/v1/document/{document.ID}" target="_blank">{document.title}</a></td>
  1. Do I need Content-Type: application/octet-stream for file download? 我需要 Content-Type: application/octet-stream 来下载文件吗?
  2. How to download file in browser from Go server 如何在浏览器中从Go服务器下载文件

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

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