SSRS create PDF or Excel from <form> POST - reporting-services

According to this Microsoft dev guidance, it should be possible to have a element on a web page do a POST via the method=POST attribute of the form. It shows an example of HTML needed in order to open a report viewer to a report and render the HTML viewer. I have that working. I would like to use the exact same technique to create a PDF or Excel file, but it doesn't work when I update the Format parameter to either PDF or EXCELOPENXML. Instead it ignores that parameter and provides the HTML viewer anyway. I would like to stick to one technique for both opening the HTML viewer and for downloading the various file formats. Does anyone know a workaround? I have considered a generic function to take the hidden elements and tack them on to the action URL, and open a new window with that. Does anyone have the code to do that?

I would still be curious to know if there's an issue with the POST action for file exports, but in the meantime, I solved it with this:
$("form").find(":input[name]").map(function(val, key) {
return encodeURIComponent($(this).attr('name'))
+ '='
+ encodeURIComponent($(this).val()).replace(/%2C/g,',').replace(/%20/g,' ');
//unencode space and comma characters for convinience and shorter URLs
}).get().join("&")

Related

How can I import html content to pdf template?

I created a pdf template with open office draw. it has textboxes and I can set values with acrofield. But I can't import a html content to template.
I can convert html contents to pdf file; but for template, how can I do it?
My problem is with template; also my html content have to map on page, for example center of page.
Thanks
I am not quite sure if I understand your question, but it seems like you need some kind of template where you will enter your content.
My thinking goes to OpenXML as the best fit. But since it is rather complex you can save some time by using third party tools.
From my experience, Docentric gives you good value for the money. You can prepare a template in Word and then merge it with data from any source that can fit into .NET object. Your document can be converted to pdf or xps if required.
Templates are generated in MS Word (2007 or newer) using special Docentric Add-in for template generation. All MS Word formatting can be applied here. Placeholders for data are set where the data will appear at runtime.
The process is straight forward so even end users can design reports. Developers then focus on bringing data in from various sources (database, XML). Chech the product documentation for ideas how to use it.

Passing info in a URL to Sharepoint

I'm new to SharePoint but I was wondering if there was a way to pass variables from an external website to a SharePoint Web Part via GET.
e.g.
http://mysharepointpage.com/sites?name=Jay&age=23 does not populate my name or age input fields in the SharePoint Web Part.
Note: I had to remove the <form method="GET"> tags because I kept getting an error advising;
<FORM> tags are not supported in the HTML specified in either the Content property or the Content Link property. You can
remove the <FORM> tag, or use the Page Viewer Web Part, which supports the HTML <FORM> tag. The Content property can
be modified in the Rich Text Editor or Source Editor. More about the Page Viewer Web Part
When I click on the link it tells me;
Cannot display help.
Technical details: HC not found.
I'm guessing this is why I can't retrieve the data via URL.
A little more information as to how would be much appreciated.
Your query string looks correct:
Connect a Query String (URL) Filter Web Part to another Web Part
You will then need to implement javascript on the page to loop through all the keys and populate the form as required.
You should be able to use this link to help you with your javascript or please post what you are currently using: Getting query string values in JavaScript

Creating custom SSRS handler for field with HTML

I have an SSRS 2008 report with a field that contains and is configured to render as HTML. Some of the text in this field may contain IMG tags, and the IMG tag is not among the tags SSRS natively supports within its HTML rendering extension.
I am trying to find a way to write a custom handler to hook into the processing of this field that will let me look at the raw HTML before the SSRS handler processes it, in the hopes of grabbing IMG tags, extracting the SRC URL and getting the raw bytes of an image to insert on the fly in a way SSRS will accept, yet retaining the HTML SSRS will render.
From what I've read and seen so far, if a field is marked to render as HTML, the SSRS processor grabs it and parses it entirely before any handler could modify it, meaning the IMG tag is (would be) discarded before I could do anything with it (or even know it was present). The only option I see is to turn off the HTML rendering entirely, thus losing the benefit of the tags SSRS can recognize.
EDIT: Per Jamie's response below, I'm beginning to think the "2nd half" of this issue may prove harder than I realized: Is it even possible to programmatically add an Image to an SSRS Report at runtime (obviously through code/custom assembly)? That is, I'd like to write some code that might look something like this (pseudocode)
'Conceptual Pseudocode I'd like to be able to write
'for dynamic addition of Image element in SSRS report
'Is this even possible?? Is there a documented Report
'object model??
Public Function AddImage(imageBytes() as Byte) as Image
Dim newImage as New Image()
newImage.SetBytes(imageBytes)
Report.Add(newImage)
return newImage
End Function
I'm hoping I'm just overlooking something simple that prevents me from grabbing the raw, unprocessed HTML, and someone else might be able to point me in the right direction on how to grab it.
EDIT: I have created and implemented this solution within the SSRS development environment and it works. WOOHOO :) It did require some hoop-jumping with creating a Single-Threaded Apartment thread to host the WebBrowser control, and to create a message pump, but it does work! **
As I was literally typing up the message to a co-worker that this issue was a non-starter, I did have a bit of an inspiration on a way to solve this problem. I know this post hasn't generated a great deal of response, but just in case someone else finds themselves in a similar problem, I'm going to share what I've implemented in a "petri dish" scenario that, provided I get all the code permission issues resolved, should allow me a decent solution to this problem.
With SSRS inability to handle an IMG tag insurmountable, I actually thought of an idea that took the HTML rendering away from SSRS entirely. To do this, I created custom code that hands off the HTML rendering to a WebBrowser control, then copies the rendered result as an image. It does the following:
Instantiates a WebBrowser control of a given width and height.
Sets the DocumentText property of that control to the HTML from TinyMCE
Waits for the DocumentText to completely render.
Creates a bitmap equal to the size of the control.
Uses the undocumented and presumably unsupported DrawToBitmap method of the WebBrowser to draw the rendered HTML to a bitmap.
Copies the Bitmap to an Image
Saves the Image as a .png file
Returns the path to the .png as the result of the function.
In SSRS, I plan to replace the erstwhile HTML text field with an external Image control that will then call the above method and render the image file. I may alter that to simply draw the image to the SSRS Image control directly, but that's a final detail I'll resolve later. I think this basic design is going to work. Its a little kludgey, but I think it will work.
I have some permissions issues to work out with the code that SSRS will allow me to call at runtime, but I'm confident I'll get those sorted out (even if I end up moving the code to a separate assembly). Once this is tested and working, I plan to mark this as the answer.
Thanks to those who offered suggestions.
I've done something similar with success: We had an HTML "Comment" field that was collected on a web form. For a particular report we wanted to truncate this field to the first 1000 characters or so, but preserve valid HTML.
So I created a C# .dll & class with a public function:
public static string TruncateHtml(string html, int characters)
{
...
}
(I used the HtmlAgilityPack for most of the HTML parsing, and to create and close off my new HTML string, while I kept track of the content length.)
Then I could call that code with the fully qualified path to the function in an SSRS expression:
=ReportHtmlHandler.HtmlTruncate.TruncateHtml(Fields!Comment.Value, 1000)
I could have added a calculated field to my dataset with this, but I was only using this value for one field, so I kept it at the field expression level.
All of this code gets called well before the HTML is processed or rendered by SSRS. I'm sure that any original IMG tag will be in the string.
This approach might work for you, possibly create a ExtractImg function which could be set as the source of an img on the report. I think some of the tricky bits for your requirement will be to handle multiple images as well as embedding the extracted img. But you might be able to do this simply with a external reference to an image. I haven't done much with external images in SSRS.
An MSDN blog entry on calling a custom dll from SSRS: http://support.microsoft.com/kb/920769

dynamic HTML page to pdf

I know there is a list of similar questions but all handle pages without user interaction (static even though some js may be there).
Let's say we've a page the user can interact (e.g. svg than changes, or html tables with drilldown - content changes). Those interactions will change the page. Same happens in stackoverflow when entering the question...
The idea is adding a button, "convert to pdf" taking the state of the html and sending to the user back a pdf version (we've a Java server).
Using the print of the browser is not the answer I'm looking for :-).
Is this a stick in the moon ?
You would have to store the parameters that generate the HTML view (i.e. what the user clicks on, what selections they make, etc). If you can have a list of parameters that generate the HTML view, you can have a method which accepts the list of parameters (JSON post?), generates the HTML view and passes it to your PDF generating routine. I'm not too familiar with Java libraries for this purpose, but PHP has TCPDF can take html output to basically generate a PDF for you. Certainly, there are Java libraries which will allow you to do the same thing, or you can use the parameters to get a list of rows/arrays which can be iterated over and output using the PDF library of your choice.
Both iTextPDF and Aspose.PDF would allow you to do that (I've seen them used in two different projects), but there is no magic and you will have to do some work.
The steps are roughly:
Get (as a string) the part of the document which you want to print with jQuery or innerHTML
Call a service on the server side to convert this to PDF
[Serverside] Use a whitlist - based tool to clean up the hmtl (unless you want to be hacked). JSoup is great for that.
[Serverside] Use IText or Aspose API to create the PDF from the HTML (this is not trivial, you will have to read the doc)
Download the document
I'd also recommend DocRaptor, an HTML to PDF API built by my company, Expected Behavior.
DocRaptor uses Prince XML to generate PDFs, and thus produces higher quality results than similar products.
Adding PDF generation to your own web application using our service is as simple as making an HTTP POST request to our server.
Here's a link to DocRaptor's home page:
DocRaptor
And a link to our API documentation:
DocRaptor API documentation

Best Way to View Generated Source of Webpage?

I'm looking for a tool that will give me the proper generated source including DOM changes made by AJAX requests for input into W3's validator. I've tried the following methods:
Web Developer Toolbar - Generates invalid source according to the doc-type (e.g. it removes the self closing portion of tags). Loses the doctype portion of the page.
Firebug - Fixes potential flaws in the source (e.g. unclosed tags). Also loses doctype portion of tags and injects the console which itself is invalid HTML.
IE Developer Toolbar - Generates invalid source according to the doc-type (e.g. it makes all tags uppercase, against XHTML spec).
Highlight + View Selection Source - Frequently difficult to get the entire page, also excludes doc-type.
Is there any program or add-on out there that will give me the exact current version of the source, without fixing or changing it in some way? So far, Firebug seems the best, but I worry it may fix some of my mistakes.
Solution
It turns out there is no exact solution to what I wanted as Justin explained. The best solution seems to be to validate the source inside of Firebug's console, even though it will contain some errors caused by Firebug. I'd also like to thank Forgotten Semicolon for explaining why "View Generated Source" doesn't match the actual source. If I could mark 2 best answers, I would.
Justin is dead on. The key point here is that HTML is just a language for describing a document. Once the browser reads it, it's gone. Open tags, close tags, and formatting are all taken care of by the parser and then go away. Any tool that shows you HTML is generating it based on the contents of the document, so it will always be valid.
I had to explain this to another web developer once, and it took a little while for him to accept it.
You can try it for yourself in any JavaScript console:
el = document.createElement('div');
el.innerHTML = "<p>Some text<P>More text";
el.innerHTML; // <p>Some text</p><p>More text</p>
The un-closed tags and uppercase tag names are gone, because that HTML was parsed and discarded after the second line.
The right way to modify the document from JavaScript is with document methods (createElement, appendChild, setAttribute, etc.) and you'll observe that there's no reference to tags or HTML syntax in any of those functions. If you're using document.write, innerHTML, or other HTML-speaking calls to modify your pages, the only way to validate it is to catch what you're putting into them and validate that HTML separately.
That said, the simplest way to get at the HTML representation of the document is this:
document.documentElement.innerHTML
[updating in response to more details in the edited question]
The problem you're running into is that, once a page is modified by ajax requests, the current HTML exists only inside the browser's DOM-- there's no longer any independent source HTML that you can validate other than what you can pull out of the DOM.
As you've observed, IE's DOM stores tags in upper case, fixes up unclosed tags, and makes lots of other alterations to the HTML it got originally. This is because browsers are generally very good at taking HTML with problems (e.g. unclosed tags) and fixing up those problems to display something useful to the user. Once the HTML has been canonicalized by IE, the original source HTML is essentially lost from the DOM's perspective, as far as I know.
Firefox most likley makes fewer of these changes, so Firebug is probably your better bet.
A final (and more labor-intensive) option may work for pages with simple ajax alterations, e.g. fetching some HTML from the server and importing this into the page inside a particular element. In that case, you can use fiddler or similar tool to manually stitch together the original HTML with the Ajax HTML. This is probably more trouble than it's worth, and is error prone, but it's one more possibility.
[Original response here to the original question]
Fiddler (http://www.fiddlertool.com/) is a free, browser-independent tool which works very well to fetch the exact HTML received by a browser. It shows you exact bytes on the wire as well as decoded/unzipped/etc content which you can feed into any HTML analysis tool. It also shows headers, timings, HTTP status, and lots of other good stuff.
You can also use fiddler to copy and rebuild requests if you want to test how a server responds to slightly different headers.
Fiddler works as a proxy server, sitting in between your browser and the website, and logs traffic going both ways.
I know this is an old post, but I just found this piece of gold. This is old (2006), but still works with IE9. I personnally added a bookmark with this.
Just copy paste this in your browser's address bar:
javascript:void(window.open("javascript:document.open(\"text/plain\");document.write(opener.document.body.parentNode.outerHTML)"))
As for firefox, web developper tool bar does the job. I usually use this, but sometimes, some dirty 3rd party asp.net controls generates differents markups based on the user agent...
EDIT
As Bryan pointed in the comment, some browser remove the javascript: part when copy/pasting in url bar. I just tested and that's the case with IE10.
If you load the document in Chrome, the Developer|Elements view will show you the HTML as fiddled by your JS code. It's not directly HTML text and you have to open (unfold) any elements of interest, but you effectively get to inspect the generated HTML.
In the Web Developer Toolbar, have you tried the Tools -> Validate HTML or Tools -> Validate Local HTML options?
The Validate HTML option sends the url to the validator, which works well with publicly facing sites. The Validate Local HTML option sends the current page's HTML to the validator, which works well with pages behind a login, or those that aren't publicly accessible.
You may also want to try View Source Chart (also as FireFox add-on). An interesting note there:
Q. Why does View Source Chart change my XHTML tags to HTML tags?
A. It doesn't. The browser is making these changes, VSC merely displays what the browser has done with your code. Most common: self closing tags lose their closing slash (/). See this article on Rendered Source for more information (archive.org).
Using the Firefox Web Developer Toolbar (https://addons.mozilla.org/en-US/firefox/addon/60)
Just go to View Source -> View Generated Source
I use it all the time for the exact same thing.
I had the same problem, and I've found here a solution:
http://ubuntuincident.wordpress.com/2011/04/15/scraping-ajax-web-pages/
So, to use Crowbar, the tool from here:
http://simile.mit.edu/wiki/Crowbar (now (2015-12) 404s)
wayback machine link:
http://web.archive.org/web/20140421160451/http://simile.mit.edu/wiki/Crowbar
It gave me the faulty, invalid HTML.
This is an old question, and here's an old answer that has once worked flawlessly for me for many years, but doesn't any more, at least not as of January 2016:
The "Generated Source" bookmarklet from SquareFree does exactly what you want -- and, unlike the otherwise fine "old gold" from #Johnny5, displays as source code (rather than being rendered normally by the browser, at least in the case of Google Chrome on Mac):
https://www.squarefree.com/bookmarklets/webdevel.html#generated_source
Unfortunately, it behaves just like the "old gold" from #Johnny5: it does not show up as source code any more. Sorry.
In Firefox, just ctrl-a (select everything on the screen) then right click "View Selection Source". This captures any changes made by JavaScript to the DOM.
alert(document.documentElement.outerHTML);
Check out "View Rendered Source" chrome extension:
https://chrome.google.com/webstore/detail/view-rendered-source/ejgngohbdedoabanmclafpkoogegdpob/
Why not type this is the urlbar?
javascript:alert(document.body.innerHTML)
In the elements tab, right click the html node > copy > copy element - then paste into an editor.
As has been mentioned above, once the source has been converted into a DOM tree, the original source no longer exists in the browser. Any changes you make will be to the DOM, not the source.
However, you can parse the modified DOM back into HTML, letting you see the "generated source".
In Chrome, open the developer tools and click the elements tab.
Right click the HTML element.
Choose copy > copy element.
Paste into an editor.
You can now see the current DOM as an HTML page.
This is not the full DOM
Note that the DOM cannot be fully represented by an HTML document. This is because the DOM has many more properties than the HTML has attributes. However this will do a reasonable job.
I think IE dev tools (F12) has; View > Source > DOM (Page)
You would need to copy and paste the DOM and save it to send to the validator.
Only thing i found is the BetterSource extension for Safari this will show you the manipulated source of the document only downside is nothing remotely like it for Firefox
The below javascript code snippet will get you the complete ajax rendered HTML generated source. Browser independent one. Enjoy :)
function outerHTML(node){
// if IE, Chrome take the internal method otherwise build one as lower versions of firefox
//does not support element.outerHTML property
return node.outerHTML || (
function(n){
var div = document.createElement('div'), h;
div.appendChild( n.cloneNode(true) );
h = div.innerHTML;
div = null;
return h;
})(node);
}
var outerhtml = outerHTML(document.getElementsByTagName('html')[0]);
var node = document.doctype;
var doctypestring="";
if(node)
{
// IE8 and below does not have document.doctype and you will get null if you access it.
doctypestring = "<!DOCTYPE "
+ node.name
+ (node.publicId ? ' PUBLIC "' + node.publicId + '"' : '')
+ (!node.publicId && node.systemId ? ' SYSTEM' : '')
+ (node.systemId ? ' "' + node.systemId + '"' : '')
+ '>';
}
else
{
// for IE8 and below you can access doctype like this
doctypestring = document.all[0].text;
}
doctypestring +outerhtml ;
I was able to solve a similar issue by logging the results of the ajax call to the console. This was the html returned and I could easily see any issues that it had.
in my .done() function of my ajax call I added console.log(results) so I could see the html in the debugger console.
function GetReversals() {
$("#getReversalsLoadingButton").removeClass("d-none");
$("#getReversalsButton").addClass("d-none");
$.ajax({
url: '/Home/LookupReversals',
data: $("#LookupReversals").serialize(),
type: 'Post',
cache: false
}).done(function (result) {
$('#reversalResults').html(result);
console.log(result);
}).fail(function (jqXHR, textStatus, errorThrown) {
//alert("There was a problem getting results. Please try again. " + jqXHR.responseText + " | " + jqXHR.statusText);
$("#reversalResults").html("<div class='text-danger'>" + jqXHR.responseText + "</div>");
}).always(function () {
$("#getReversalsLoadingButton").addClass("d-none");
$("#getReversalsButton").removeClass("d-none");
});
}