1

I've got a .net web service with a method which creates an iTextSharp PDF document.

I've got a Cordova / JqueryMobile based app which calls this method on one of its views.

The web service sends the document as a byte stream.

I cannot get the Cordova app to display the file.

The web service

<OperationContract()> _
<WebInvoke(Method:="POST", ResponseFormat:=WebMessageFormat.Json)> _
Public Function GetPDF(ByVal accountID As Int64) As Byte()
    Dim myPDF As Document = New Document

    Dim msPDFData As MemoryStream = New MemoryStream()
    Dim writer As PdfWriter = PdfWriter.GetInstance(myPDF, msPDFData)
    myPDF.Open()
    myPDF.Add(New Paragraph("I'm a pdf!"))

    Dim pdfData As Byte() = msPDFData.ToArray()

    Return pdfData
End Function

Very simple.

The ajax call

var dataString = JSON.stringify({
    accountID: '309'
});

$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    url: '/GetPDF',
    data: dataString,
    processData: true,
    dataType: "json",
    success: function (response) {
    var reader = new FileReader();        
    reader.readAsArrayBuffer(response.d);
    reader.onloadend = function (evt) {
        console.log("read success");
        console.log(new Uint8Array(evt.target.result));
    };
    },
    error: function (a, b, c) {
        alert('file error')
    }
});

This isn't doing anything. But response.d does contain what seems to be the bytes of the document.

I am want Cordova to parse the byte array and open a PDF reader to display the document, with the option to save the file.

I thought I could use the FileTransfer.download Cordova method, but the example has a fixed uri, whereas I would need to call a web service and I haven't yet been able to swap that fixed uri with my ajax call - so I don't know if that is the answer.

DaveSav
  • 1,364
  • 5
  • 21
  • 41
  • Have you verified that you are generating a valid PDF? Last I remember you need to call `Close()` on your document before using it. Are you getting an exception or anything on the Cordova side? – Chris Haas Jul 25 '14 at 22:54
  • Thanks, I wasn't calling close() on the document. – DaveSav Jul 26 '14 at 20:23

1 Answers1

2

I found the answer, with the help of Saurabh at this SO question

In my original implementation, I was hoping to somehow open the file directly from the stream. But it turns out you have to create a physical file and write the data to that and then open it.

So, my updated code converts the byte array from the webservice into a binary array, and then write that to the file:

var dte = getCurDateOnly(), fileData, UTF8_STR, BINARY_ARR, dataString = JSON.stringify({
    accountID: '309'
});

$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    url: '/GetPDF',
    data: dataString,
    processData: true,
    dataType: "json",
    success: function (response) {
        fileData = response.d;
        UTF8_STR = new Uint8Array(response.d);  // Convert to UTF-8...                
        BINARY_ARR = UTF8_STR.buffer; // Convert to buffer...
        getFS();
    },
    error: function (a, b, c) {
        alert('file error')
    }
});

function getFS() {
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
}

function gotFS(fileSystem) {
    fileSystem.root.getDirectory("MyDIR", { create: true }, gotDir);
}

function gotDir(dirEntry) {
    dirEntry.getFile("MyFILE" + dte + ".pdf", { create: true, exclusive: false }, gotFile);
}

function gotFile(fileEntry) {
    fileEntry.createWriter(function (writer) {
        writer.onwrite = function (evt) {
            console.log("write success");
            listDir();
        };
        writer.write(BINARY_ARR);
    }, function (error) {
        console.log(error);
    });
}
function fail() {
    console.log('pdf fail function called');
}

Thanks to Saurabh for the final piece of the puzzle.

Community
  • 1
  • 1
DaveSav
  • 1,364
  • 5
  • 21
  • 41
  • I've tried this with a JPEG image but it doesn't quite seem to work. If I'm setting the image.src to the file that was written with the writer.write function, it just shows a small grey box instead of the actual image. Any suggestions on that? – plocks Oct 14 '14 at 14:44