I didn’t start out to make this a love story. In fact, I started out with this being what I thought would be a somewhat easy task. We had a client who wanted to generate a PDF from HTML. Tons of tools to do that, no heavy lifting, seemed like a piece of cake. I’d never done it, but it didn’t seem too bad, so I began courting the different PDF conversion tools. As with all relationships, it started out fun. There were a lot of paid options, a few free ones (though you had to be careful of the licensing and usages) and even more that you had to take out to either a small dinner, large dinner, and a couple of enterprise solutions that expected a house payment. So, after going on a few dates with some good candidates I ended up deciding on SelectPDF. (http://selectpdf.com/  for those wanting to follow along at home.) I liked the fact I could just give it a url and it would magically convert that into a PDF.

A few hour courtship and then we’re married right?

Not so fast.

Our tale begins with the HTML.

The first thing I had to do was take the report that was required for the MVP and mock it out in an HTML view. My first issue was I needed to do some bar graphing and so I went to my favorite graphing hangout, D3J (https://d3js.org/) If you’ve never used it, take a few weeks and get acquainted. For the purposes of this post lets just assume you know how it works.

I built a REST endpoint to return back data, wired it up with the bar graph, then built another endpoint to populate a datagrid (not an old school MS datagrid, but the same general principle, bound to the API return JSON) and spent some time with the CSS and dressed it up pretty so that we could go out on the town and everyone would really stare at how beautiful we were.

I had my HTML together, had my REST API endpoints, and had it looking good at home (localhost) and so I decided it was time to take this HTML relationship to the next level. That’s right, we were going to go from being just HTML to being full blown PDF….

But how does one start?

As mentioned at the beginning of our tale, I’d already selected SelectPDF and so I wired up the HTML to the PDF conversion and crossed my fingers.

That’s when things got rocky.

The majority of the HTML to PDF conversion tools were built to convert pure HTML. One of my earlier selections broke with convention, the fact that I used D3J. The issue there, is that if you break open the source and look at the rendering of a D3J you will see that it’s actually an SVG which per wikipedia (Scalable Vector Graphics (SVG) is an XML-based vector image format for two-dimensional graphics with support for interactivity and animation) so it’s not actually HTML. Because of that, I noticed there were no graphs on the generated PDF.

So it was back to square one. I told SelectPDF, “it’s not me, it’s you,” and I got back out there. I courted a few more of the earlier tools but found a lot of them didn’t support what I needed and so I scoured my notes looking for something I might have missed, and wouldn’t you know it, there in the mass of forgotten letters I found that SelectPDF did in fact support SVG.

Then where were my graphs?

I called SelectPDF back up, told it I’d made a mistake and that I’d like another chance. SelectPDF, being the reasonable tool that it was said, “sure, we can try it again,” and so I loaded up the code and went for it.

What I found surprised me.

It appeared that if I allowed the code to slow down, aka, run it with breakpoints during the conversion piece, that the graphs would in fact render. There appeared to be a timing issue between the time when the URL rendered and the point at which SelectPDF began to actually convert the page. I tried to find an event of some kind to check for completion but the only thing I could find was a result property: var resul = converter.ConversionResult; which did seem to enhance the capacity of the the SVG to show up.

Sounds like even though SelectPDF was the closest I found to what I need, it was still a little flaky, but hey, we all have our limitations.

I felt good about my relationship with SelectPDF and the conversion of D3J and HTML and was super happy. I thought to myself, “hey, it’s time to make this relationship public” and so I went to my favorite platform, Microsoft Azure, since I wanted this to be available in the cloud. I thought that all my heavy lifting was done. I’d struggled to find the right tool to convert HTML to PDF. I’d found the battle of SVG to PDF. Now, all I needed to do was sit back, right-click publish, and I’d be off to the races?

Think again.

I created my Azure Web app, got the storage tables aligned, got my deployment profile, clicked publish and you know what? Azure Web Apps didn’t seem to feel the same way I did about SelectPDF. The report that ran so well at home wouldn’t run at all on Azure.

So I thought to myself, if this an Azure issue or is this simply a Web App issue. I dug through the internet looking for others who may have had a great relationship with SelectPDF only to find that when they went to make the relationship public on Azure they were shut down. Turns out, from the SelectPDF family themselves:

“If you plan to deploy Select.Pdf to Windows Azure, make sure you deploy to a Cloud Service or a Virtual Machine. Due to some security restrictions, Select.Pdf does not support Windows Azure WebSite execution mode. To resolve the issue, you can either deploy your site to a Cloud Service or a Virtual Machine, or isolate the PDF related feature into a separate Web Service that runs on a different server (either on a Windows Azure Cloud Service/Virtual Machine, or a dedicated server hosted elsewhere), then call the web service from your Windows Azure WebSite.”

Well, that’s an annoyance but not a deal breaker. I’ve devoted too much time already to the architecture of the solution and so to give up now, well that would just be giving up, and I refused to give up on SelectPDF. I knew that we had a future together, this was just the early stages, and things were often rocky.

So, off I went to Azure to spin up a Cloud Service. I connected it up, build the web role, converted my Web App (API) project to a WebRole, deployed, and once again crossed my fingers. To my chagrin, I was met with the following message:

<string xmlns=”http://schemas.microsoft.com/2003/10/Serialization/”>
Conversion failure. Could not find ‘Select.Html.dep’.
</string>

What the heck is Select.Html.dep you might ask? Well, I asked the same thing. Turns out, it’s a setup Wizard dependency file. A dependency (DEP) file contains information about the run-time requirements of a solution or component.

Well okay, cool, all I need to do is deploy that file and all will be great, right?

Wrong.

When you deploy an Azure Cloud Service, usually everything get’s bundled and pushed and all is right with the world. However, a dep file is not a .dll file and the .dep file is required to be in the same folder as the .dll that it’s partnered with. That being said, I tried to add the .dep as content, I tried to add the “Copy Always” to force it out, and no matter what I did I kept getting:

<string xmlns=”http://schemas.microsoft.com/2003/10/Serialization/”>
Conversion failure. Could not find ‘Select.Html.dep’.
</string>

I knew what I had to do, though I was beginning to wonder if there were too many partners in this relationship. Azure was okay with SelectPDF it just didn’t want to let .dep in to the party. SelectPDF didn’t want to get along with SVG, and poor HTML was just sitting there talking about how it hadn’t changed since 1990 and it missed grunge music and flannel, but I’d come too far. I had to see it through.

I knew there was only one hope left. I would have to go over to Azure’s house and tell it that it had to accept .dep, otherwise the whole thing would fall apart. However, getting Azure to open up is no easy task. You can’t just click on an icon in the portal.azure.com and have it let you in. Instead, you have to use an intermediary, PowerShell, and powershell isn’t very GUI, you have to get console with it. The first thing I had to do was open Powershell and browse to the Cloud Service directory. There is a .csdef file there that we have to modify to allow Remote Desktop access.

Yes, I said Remote Desktop.

I know.

Truly, I know.

I ran the Powershell script and modified the .csdef file and went out to Azure to try to get Remote Access.

Couldn’t do it.

“What to do now?” I pondered, then realized that I had to republish the modified .csdef file. Rookie mistake, but I was so tired from having to deal with so many disparate systems that I wasn’t thinking straight. I republished and then went back out to the Azure where Azure told me, “yeah, I see you’ve been in Powershell and think you’re cool. I guess I’ll let you see my VM file system.”

So there I was, staring at what was essentially a Windows Server of old, looking for the place to put my .dep file.

I know what you’re thinking, surely it’s all good now right?

Come on now, you know better than that.

First off, I have no shared port or email access on this VM so I can’t get the file anywhere on it. Luckily, this is an easy fix. I go back out to Azure, get the Remote Session, modifiy the file to allow local machine access, and BOOM! I can copy and paste. Now the issue is where to copy and paste to.

I thought Azure would follow the normal publishing patterns on the file system. Why I thought anything would be familiar is beyond me, but there it was, on the E: drive, under approot, my published code! I was ecstatic. I dropped my .dep file in, went back and tried to run my report.

<string xmlns=”http://schemas.microsoft.com/2003/10/Serialization/”>
Conversion failure. Could not find ‘Select.Html.dep’.
</string>

What? Really? Come on.

So, being an old IIS coder, I thought, hey, let’s just go make sure the file system paths are what I think they should be. So I load it up, find the website, check the path and lo and behold instead of being at approot, it was living under E:\sitesroot\0. The 0 was an interesting touch, but I assumed it was just the 0’th element since this was the only Webrole I had on this CloudService.

I crossed my fingers again (by this time I’m getting calluses) and ran my report. To my complete and utter amazement, there was no error and magically, an HTML report written with DJ3 which rendered in SVG was converted through SelectPDF and showed up (via a SendGrid email) in my East Five email account. We had come full circle.

I gathered everything together and told them that I had learned a lot. At first there was frustration and confusion, fear and uncertainty, but after going through so much with so many systems I felt that I might have found a way to appreciate all of them for what they are and what they offer, and at the end of the day, I think that’s the definition (at least loosely) of love.