简体   繁体   English

在HTML中显示pdf时的奇怪行为

[英]Strange behavior when displaying pdf in HTML

About the stack and data: 关于堆栈和数据:


I've been working on displaying a PDF in our AngularJS Kiosk application since late yesterday evening, but have gotten stuck on multiple occasions. 从昨天晚上开始,我一直在AngularJS Kiosk应用程序中显示PDF,但是在很多情况下都卡住了。

Currently I've got a table in our SQL Server database that holds some data, one of the fields being a varbinary(max) representation of a PDF. 目前,我在SQL Server数据库中有一个表,其中包含一些数据,其中一个字段是PDF的varbinary(max)表示形式。

This data is returned through a C# REST WebAPI which returns JSON objects (where obviously the PDF varbinary is a byte[] . 该数据通过C#REST WebAPI返回,该WebAPI返回JSON对象(显然,PDF varbinarybyte[]

Each PDF is assigned to a specific role and place of work. 每个PDF都分配有特定的角色和工作地点。 As it is right now this is all bundled up in the returned JSON object . 现在,所有这些都捆绑在返回的JSON对象中


The Problem: 问题:

This current implmentation has worked absolutely fine for displaying images, but now that I'm working with a PDF I seem to: 当前的实现对于显示图像已经非常有用,但是现在我正在使用PDF,我似乎可以:

a.) Either get some missrepresentation of the data; a。)要么得到数据的一些错误陈述;要么 the pdf might be upside down, some text might be backwards or parts of the pdf might follow as upside down. pdf可能会颠倒,某些文本可能会倒转,或者pdf的某些部分可能会颠倒。 (When using pdf.js) (使用pdf.js时)

b.) The PDF doesn't display because there is no data in it or the worker gets destroyed (angular-pdf) . b。)由于其中没有数据或工作程序被销毁(angular-pdf) ,因此无法显示PDF

I'm now back to using pdf.js, so scenario a.) keeps occurring. 我现在回到使用pdf.js,因此情况a。)一直在发生。


Code: 码:

This is how I pull out the data using Angular: 这就是我使用Angular提取数据的方式:

$http.post("http://some-example.com/api/PDF/Get", JSON.stringify(vm.content))
    .then(function (response) {
        //success

        vm.data = response.data;
        $sce.trustAsResourceUrl(vm.data[0].Pdf);
    },
    function (error) { 

    })
    .finally(function () {
        let pdf = atob(vm.data[0].Pdf);
        let loadingTask = PDFJS.getDocument({ data: pdf }); 

        loadingTask.promise.then(function (pdf) { 

            let pageNumber = 1;
            pdf.getPage(pageNumber).then(function (page) {
                let scale = 1;
                let viewport = page.getViewport(scale);

                let canvas = document.getElementById('test-canvas');
                let context = canvas.getContext('2d');
                canvas.height = viewport.height;
                canvas.width = viewport.width;

                let renderContext = {
                    canvasContext: context,
                    viewport: viewport
                };
                let renderTask = page.render(renderContext);
                renderTask.then(function () { 
                    // Wait for rendering to finish
                    renderTask.promise.then(function () {
                        pageRendering = false;
                        if (pageNumPending !== null) {
                            // New page rendering is pending
                            renderPage(pageNumPending);
                            pageNumPending = null;
                        }
                    });
                }); 
            });
        });
    });

Checking out the Pdf of the returned object it seems to be of type string and seems to have a decoded binary value as the Pdf value in the database is encoded. 检出返回对象的Pdf ,它似乎是string类型,并且由于对数据库中的Pdf值进行了编码,因此似乎具有已解码的二进制值。

This is how the data is returned by my REST API (C#): 这是我的REST API(C#)返回数据的方式:

[HttpPost]
public HttpResponseMessage Get(int get_id = 0)
{
    HttpContent req = Request.Content;
    int val = 0;
    string jsonContent = req.ReadAsStringAsync().Result;
    JObject jobobj = JObject.Parse(jsonContent);
    string where = null;
    List<test_pdf_table> list = new List<test_pdf_table>();
    DataSet ds = null;

    try
    {
        where = (jobobj["where"] == null) ? null : (string)jobobj["where"];
        string strcon = ConfigurationManager.ConnectionStrings[(string)jobobj["strcon"]].ConnectionString;
        ds =  dc.FETCHtest_pdf_table((where == null) ? "Where ID = " + get_id : where, (strcon == null) ? conStr : strcon, "REST");
    }

    catch (Exception e)
    {
        return Request.CreateResponse(HttpStatusCode.InternalServerError, e.ToString());
    }

    if (where == null) 
    {
        ds = dc.FETCHtest_pdf_table("WHERE ID = " + get_id, conStr, "REST");
    } 
    else 
    {
        ds = dc.FETCHtest_pdf_table(where, conStr, "");
    }

    foreach (DataTable table in ds.Tables)
    {

        foreach (DataRow row in table.Rows)
        {
            int? id = row["ID"] as int?;
            int? userid = row["UserID"] as int?;
            int? worksiteid = row["WorksiteID"] as int?;
            Byte[] pdf = row["Pdf"] as Byte[];
            String path = row["Path"] as String;

        list.Add(new test_pdf_table
                {
                    ID = id,
                    UserID = userid,
                    WorksiteID = worksiteid,
                    Pdf = pdf,
                    Path = path
            });
        }
    } 
    return Request.CreateResponse(HttpStatusCode.OK, list);
}

And finally this is how I am displaying it: 最后,这就是我的显示方式:

<canvas id="test-canvas"></canvas>

To re-iterate: 要重申:

The PDF DOES display, but it comes out different every time. PDF 确实会显示,但每次都会显示不同。 It could be that it's upside down, part of text is backwards or that some of the text is displayed twice (like the PDF has been flipped) upside-down. 可能是上下颠倒,部分文本向后,或者某些文本上下颠倒显示了两次(例如PDF已翻转)。

You can try to delete the canvas before each render. 您可以尝试在每次渲染之前删除画布。 It's ugly, but it does fix the rendering problem. 这很丑陋,但确实可以解决渲染问题。 Hopefully future versions of PDFJS will work without this hack: 希望将来的PDFJS版本可以在没有这种黑客的情况下工作:

let canvas = document.getElementById('test-canvas'),
parent = canvas.parentNode,
context;

parent.removeChild(canvas);
canvas = document.createElement('canvas');
canvas.id = 'test-canvas';
parent.insertBefore(canvas, parent.childNodes[0]);
context = canvas.getContext('2d');

canvas.height = viewport.height;
canvas.width = viewport.width;

let renderContext = {
    canvasContext: context,
    viewport: viewport
};

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

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