Exploring the stack and data:
I've been diligently working on integrating a PDF display feature into our AngularJS Kiosk application since yesterday evening. However, I have encountered multiple roadblocks in the process.
At present, I have a table in our SQL Server database that stores various data, including a field containing a varbinary(max)
representation of a PDF file.
This data is fetched via a C# REST WebAPI, which returns JSON objects where the PDF varbinary
is converted to a byte[]
format.
Each PDF file is linked to a specific role and workplace. Currently, this information is bundled within the returned JSON object.
The Issue at Hand:
While my current implementation works perfectly for displaying images, running into problems arises when dealing with PDF files:
a.) The PDF content may be distorted; appearing upside down, having text displayed backwards, or even parts of the content being flipped. (Occurs when using pdf.js)
b.) In some cases, the PDF fails to load due to missing data or errors causing destruction of the worker thread(angular-pdf).
Upon reverting back to using pdf.js, scenario a.) continues to persist.
Code Snippet:
This is how I extract the data using 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;
}
});
});
});
});
});
Upon inspecting the Pdf
property of the returned object, it appears to be of type string
and displays a decoded binary value, as the Pdf value stored in the database is encoded.
Here's how the REST API (C#) retrieves and processes the data:
[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);
}
Lastly, here is how I am rendering the PDF content:
<canvas id="test-canvas"></canvas>
To Summarize:
The PDF IS displayed successfully, but with inconsistent results each time. There are instances where the orientation is incorrect, text appears reversed, or duplication of content occurs (as if the PDF has been mirrored) upside-down.