Save view as html file after rendering - javascript

Is it possible to save a rendered view as html file?
I need to save a view as an "Testfile.html" after Razor and javascript has rendered. Is it possible?
What i am trying to do, is take the saved view, that includes canvas created using chart.js, and save them as an html file. Afterwards i want to convert the html file to a pdf using iText7

Take a look on the below code :
First of all there is no need to save the HTML as a physical file, you can just call the razor engine renderer from within your controller, for example, so as to return the final string response.
public string RenderRazorViewToString(string viewName, object model)
{
ViewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}
Then you can pass this response to your exporter so that it can return to you the pdf file, that you will later on return directly to the client
string htmlContent = RenderRazorViewToString("SomeViewDefinedAsPartial", ReportModel);
//// fetch view's pdf styles
string CSSContent = "";
var byteRslt = PDFExporter.ConvertToPDF(htmlContent, CSSContent);
Important: HTML to PDF renderers usually dont play well enough with dynamic pages that require javascript to do initializations, but i hope this answer will help you move forwards in your requirement/implementation.

You can directly convert the View to pdf file using wkhtmltopdf
wkhtmltopdf need to be installed on the server and its path is used in the web.config from here the c# code will use this path and convert it to pdf file.

Related

How to parse HTML data from JSON and render it in UIWebView (using Swift 3.0)

I'd like to use JSON2HTML to parse the HTML data from JSON and render it in an UIWebView (using Swift 3.0). Please let me know how to achieve it. Thanks in advance!
Here's what I've tried:
let jsfile1 = try!String(contentsOfFile: Bundle.main.path(forResource: "json2html", ofType: "js")!)
func loadJS()
{
var getData={}
var context = JSContext()
var valSwiftyJson:JSON = [:]
var test = context?.evaluateScript(jsfile1)
let testFunction = test?.objectForKeyedSubscript("json2html")
let urlString = //Have removed the URL string due to restrictions
Alamofire.request(urlString,encoding:JSONEncoding.default).responseJSON
{ response in
if let alamoJson = response.result.value
{
let swiftyJson = JSON(data:response.data!)
valSwiftyJson = swiftyJson["FormInfo"]["Form"]
print(valSwiftyJson)
}
}
let result = testFunction?.call(withArguments: [getData,valSwiftyJson])
webView.loadHTMLString((result?.toString())!, baseURL: nil)
}
Finally, I managed to solve the issue by creating an index.html file (locally stored) and I referred the JSON2HTML library inside it. I then added the JSON(HTML inside) content dynamically to it each time whenever I needed to convert JSON to HTML. At last I load the final index.html in the UIWebView (it worked like charm).
Are you talking about this library as JSON2HTML ? If so, I don't think there is a library for translating the JSON elements to HTML in Swift.
Do you plan to download the JSON elements from a back-end ? Then, as there is a node.js wrapper to JSON2HTML, I would recommend to do the translating from JSON to HTML on the same server. Thus you would just download the HTML compiled data and rendering it in the UIWebView would be as easy as this line of code (in Swift 3) :
// html is the HTML data downloaded from your back-end
webView.mainFrame.loadHTMLString(html, baseURL: nil)

How to stream media content from Spring Boot endpoint for javascript client

I have a spring boot rest service with endpoints defined like this:
#RequestMapping(value = "...", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE) //and octet for videos
#ResponseBody
public ResponseEntity<byte[]> get(...) {
//get image as byte array and return
}
And the client side in javascript (angular) :
var headers = {headers : {..., "Accept":"image/jpeg"}}
var response = $http.get(...);
obj.imageSrc = 'data:image/jpg;base64,' + response;
obj.Image = new Image();
obj.Image.src = obj.imageSrc;
What I require
I thought this endpoint would behave like a regular image file on a file server so that the client can just do a get on it (for reasons outside the scope of this question, it can't actually be a raw image to access with a URL). Apparently this isn't the case - the byte array has to be converted to base64 (is there a way around this, since the array becomes much bigger), which has the effect of rotating the image. I wrongly thought getting an image from an API like this in javascript would be easy :(
Secondly, doing it this way means that javascript has to download the entire array. Is there a way I can define the endpoint to allow for a stream so that javascript can get it in chunks (I imagine both Spring and JS have utility functions that would handle this?)
The basic underlying question
How do I implement this properly in Spring so as to be as Javascript friendly as possible? Bearing in mind I want to serve both images (~5MB) and videos (~100MB)
Thanks in advance.
EDIT
Perhaps I should be using FileResourceStream as the return type? No idea if this is the "right" way.
1) Don't use a data url. Use the direct url of your controller-method.
2) Write directly to the http-response's output:
#RequestMapping(value = "/dyna.jpg", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
public void getImage(HttpServletResponse response) {
//write byte-array or -stream to the response using
// response.getOutputStream()
}
P.S. In case you really need the data url there is no otherway around as you do it, since they require the base64 encoding

Node JS, Ideas on Template For PDF Creation

How to create PDF Documents in Node.JS.? Is there any better solution to manage templates for different types of PDF creation.
I am using PDFKit to create PDF Documents and this will be server side using Javascript. I can not use HTML to create PDF. It will blob of paragraphs and sections with replacing tags with in.
Does anyone know Node.js has any npm package that can deal templates with paragraphs sections headers.
Something like
getTemplateByID() returns a template that contains sections , headers, paragraphs and then i use to replace appropriate tags within the template.
In my case, I have to get my HTML template from my database (PostgreSQL) stocked as stream. I request the db to get my template and I create a tmp file.
Inside my template, I have AngularJS tags so I compile this template with datas thanks to the 'ng-node-compile' module:
var ngCompile = require('ng-node-compile');
var ngEnvironment = new ngCompile();
var templateHTML = getTemplateById(id);
templateHTML = ngEnvironment.$compile(templateHTML)(datas);
Now I have my compiled template (where you can set your paragraph etc.) and I convert them into PDF thanks to a PhantomJS module 'phantom-html-to-pdf'
var phantomHTML2PDF = require('phantom-html-to-pdf')(options);
phantomHTML2PDF(convertOptions, function (error, pdf) {
if(error) console.log(error);
// Here you have 'pdf.stream.path' which is your tmp PDF file
callback(pdf);
});
Now you have your compiled and converted template (pdf), you can do whatever you want ! :)
Useful links:
https://github.com/MoLow/ng-node-compile
https://github.com/pofider/phantom-html-to-pdf
I hope this help !

IE 9/10/11 not rendering images after some unknown threshold

I am building an app that pulls files from SharePoint 2013 or SharePoint 2010 for view in HTML. In C#, files are pulled out of SharePoint (multipage documents like Word, Excel, PDF, TIFF, etc), then are fed into various 3rd party software (DataLogics and Aspose) - which break the documents down into their individual pages, then streams the individual pages to the browser in PNG format.
So in HTML, we have an img element whose src is set to a specific URL in an ASHX service. The ASHX service grabs the file out of SharePoint and, based on query string params, returns the desired page as a Stream.
Here is how we shoot it back:
[WebService(Namespace = "url")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class FileTransfer : IHttpHandler, IReadOnlySessionState
{
public void ProcessRequest(HttpContext context)
var stream = GetStream(context.Request);
int chunkSize = 2097152; //2MB
byte[] chunk = new byte[chunkSize];
int bytesRead = 0;
do {
bytesRead = stream.Read(chunk, 0, chunkSize);
HttpContext.Current.Response.OutputStream.Write(chunk, 0, bytesRead);
}
while (bytesRead > 0);
}
This works perfectly 100% of the time in any browser when the file we are breaking down comes directly from SharePoint.
We also provide a feature where the user can upload a document. This is where the problem comes in. Uploaded documents are not saved in SharePoint. Instead their data is stored in SessionState until the user chooses to save. Files are uploaded to an ASMX service, then the browser requests their individual pages via the above ASHX.
Files are uploaded like this in an ASMX service:
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
Public object Upload()
{
var request = HttpContext.Current.Request;
if (request.Files.Count == 1)
{
var uniqueId = request["uniqueId"];
var file = request.Files[0];
using (var memoryStream = new MemoryStream())
{
file.InputStream.CopyTo(memoryStream);
docInfo = UploadItem(uniqueId, pageNum, memoryStream.ToArray());
}
}
}
UploadItem adds the uniqueId and byte[] to SessionState.
Files are sent from javascript like this (FileUpload being tied to the change event of an input of type=file):
this.FileUpload = function (files) {
var upload = new XMLHttpRequest();
upload.onreadystatechange = () => {
if (this._curUploadRequest.readyState == 4) {
// handle response
}
};
UpdateFormDigest((<any>window)._spPageContextInfo.webServerRelativeUrl,(<any>window)._spFormDigestRefreshInterval);
var data = new FormData();
data.append("uniqueId", uniqueId);
data.append("pageNum", pageNum);
data.append("data", files[0]);
upload.open('POST', "myurl");
upload.setRequestHeader("X-RequestDigest", $("#__REQUESTDIGEST").val());
upload.send(data);
};
Now we come to the actual bug.
Images are rendered using:
<img src="url to ASHX service" />
In FireFox and Chrome, page images from uploaded documents always show up just fine. But in IE (9, 10, or 11), it renders only the first portion of them, then shows broken image icons on the image placeholders. For these broken images, the NET tab of IE shows it received 0kb and the error event is hit. But if I put a breakpoint in the ASHX just before it returns the stream, it always has a size.
More interestingly, if you take the url that the src is pointed to, open a new window and paste it in, the image shows up just fine.
I even tried to load the images in javascript first like this:
var img = new Image();
img.onload = function(){
// use jquery to append image to page
};
img.src = "url to ASHX service";
In this scenario, Chrome and Firefox work fine as usual, but IE fails again. Except this way, the NET tab of IE shows it received the correct size kb in response. However, it still shows the broken image icon and won't render images to the screen after some unknown threshold. The first several images come back, but once one breaks, all of the rest break.
I also modified the ASHX service to return base64 data instead of a stream, then bound the base64 to the src. In the debugger you can see the base64 assigned to the src of the img elements that show the broken image icon. So the data is there for sure, but IE just isn't rendering it...
I tried to recreate this problem outside of our SharePoint environment in this fiddle using knockout JS. Basically, I grab a ton of big images and throw them on the screen with each button click. But it works just fine. It works perfectly if I use jQuery too.
http://jsfiddle.net/bsdez92f/
Not sure where to go from here.
Any ideas?
So it turns out that the image size was causing a problem. I scaled the images down to thumbnail size on the server side and returned that to the browser. All is working fine at this point.

How to print a PDF from a web page

Does anybody know how to make a print page button print a pdf document?
At the moment i'm using
Print Page
Obviously that just prints the page though. I have had to create pdf's for each page and thought it would be easier just to print the pdf instead of the page (Cross browser printing styles is kinda sucking ;).
Any ideas?
There is no standard way to print anything in PDF in any browser, such as on the Windows platform. On the Mac, there is always an option to print something as a PDF file, so regular printing will do.
I suggest you use Itextsharp. If you are using asp.net c#, this code works for you. Runs in the server side though. You can just put the html inside a panel to make it readable in the server.
/// import these namespaces
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.html.simpleparser;
using System.Web.Services;
using System.Text;
/// Call this method whenever you need to convert
/// the html content inside the panel which runs in the server side.
[WebMethod]
public void ConvertHtmlStringToPDF()
{
StringBuilder sb = new StringBuilder();
StringWriter tw = new StringWriter(sb);
HtmlTextWriter hw = new HtmlTextWriter(tw);
pnlPDF.RenderControl(hw);
string htmlDisplayText = sb.ToString();
Document document = new Document();
MemoryStream ms = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(document, ms);
StringReader se = new StringReader(htmlDisplayText);
HTMLWorker obj = new HTMLWorker(document);
document.Open();
obj.Parse(se);
// step 5: we close the document
document.Close();
Response.Clear();
Response.AddHeader("content-disposition", "attachment; filename=report.pdf");
Response.ContentType = "application/pdf";
Response.Buffer = true;
Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
Response.OutputStream.Flush();
Response.End();
}

Categories