SAPUI5/ OPENUI5 javascript view HTML element render - javascript

I am new to SAPUI5/ OPENUI5 I have created a javascript view which basically imports several graphs and chart library and like a utility, it creates multiple charts and graphs and tables with icons
below is the code for the same
below is Js (sap ui JS view which creates graph)
jQuery.sap.require("some.graph.lib");
jQuery.sap.require("some.util.lib");
jQuery.sap.require("some.other.imports");
(function(){
sas.hc.ui.core.mvc.JSView.extend(" reports.dashboard.BaseDashboard.prototype.addCrossTab", {
metadata : {
properties : {
chartRequired:false,
tableDataRequired:false
},
},
rb: sap.ui.getCore().getLibraryResourceBundle("sas.csb.common"),
reports.dashboard.BaseDashboard.prototype.createGraphics = function (data) {
//This Function creates barchart, line charts and cross tab tables
return this.mainContentPane;
};
//Some other code to create and render graph
})();
I am creating another view in which I am importing above view and making ajax call so that I can create graphs and tables and send it as base64 encoded string to REST API to save into a PDF at the server side.
jQuery.sap.require("sas.cscommon.util.JSONUtil");
jQuery.sap.require({modName: "reports.dashboard.MeasureDashboard", type: "view"});
(function(){
var rb = sap.ui.getCore().getLibraryResourceBundle("sas.csb.backtesting");
//some other method
sas.csb.backtesting.ModelList.prototype.downloadModelReport = function(event) {
var id = "sample";
var oView = new reports.dashboard.MeasureDashboard(id, {
viewName: "reports.dashboard.MeasureDashboard",
chartrequired: true
} );
//Calling REST API to get data
oView.createGraphics(data);
}
How to convert this javascript sapui5 oView Object without displaying it to the user into the HTML element so that I can have the canvas and other graphics to convert into a base 64 encoded string and pass it to REST API to save at server end ?
I want to access the canvas html element from the view object without rendering the view on screen.
I know there is a renderer attached with sapui5 control and RenderManager in sapui5 but its not helping.

Sadly the methods for getting the HTML directly were deprecated. But you can create a temporary Element which is not in DOM.
var div = document.createElement("div");
var rm = sap.ui.getCore().createRenderManager();
rm.render(oView, div);
rm.destroy();
var sHTML = div.innerHTML;

Related

Save view as html file after rendering

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.

Export a Birt report at run time to a PDF file

How do you export a birt report using javascript at runtime?
The code that I have tried is in the After Render event:
importPackage(Packages.org.eclipse.birt.report.engine.api);
rptdoc = reportContext.getReportRunnable().getReportName();
// Open the rptDocument
reportDocument = getReportEngine().openReportDocument(rptdoc);
// Create the render task, configured for the wanted export format
IRenderTask renderTask = getReportEngine().createRenderTask(reportDocument);
IRenderOption options = new RenderOption();
options.setOutputFormat("pdf");
options.setOutputFileName("C:/test/myfile.pdf");
renderTask.setRenderOption(options);
// Launch the render task and close it
renderTask.render();
renderTask.close();
// Close the rptDocument
reportDocument.close();
It runs and there are no errors but no pdf gets generated...
My requirement is to run the birt report using an URL and the report should generate itself in a folder as a pdf.
The report should only execute once. I don't want to execute the URL and then in the report it does another runAndRender in after factory, the report should export itself. Hope this makes sense.
I am using Birt 4.5.
UPDATED CODE.
I can get it working using the following code in the afterRender event of the report.
//Import Lib for birt this is standard, Import our custom birt report java lib
importPackage(Packages.org.eclipse.birt.report.engine.api);
importPackage(Packages.company.reports.data);
//Creates an instance of our custom class
st = new Packages.company.reports.data.MyStandardFunctions();
//Get Global vaiables
fileDir = reportContext.getGlobalVariable("fileDir");
sTcNumber = reportContext.getGlobalVariable("sTcNumber");
sTcRevNum = reportContext.getGlobalVariable("sTcRevNum");
sTcType = reportContext.getGlobalVariable("sTcType");
sPdfPath = reportContext.getGlobalVariable("sPdfPath");
bHasErrors = reportContext.getGlobalVariable("bHasErrors");
testCertError = reportContext.getGlobalVariable("testCertError");
var re = reportContext.getReportRunnable().getReportEngine();
//Get current dreport
var pathOfReport = reportContext.getReportRunnable().getReportName().replace("file:", "");
//Create a directory for temp export reports TempExport is my dir name.
fileDir = st.createOrGetDir(fileDir);
//Only export to pdf if there were no errors.
if(bHasErrors == false)
{
var des = re.openReportDesign(pathOfReport);
var ntask = re.createRunAndRenderTask(des);
//Set parameters ie. ntask.setParameterValue("sOpiid", params["sOpiid"].value);
ntask.setParameterValue("createPDF", false);
ntask.setParameterValue("TCNumber", sTcNumber);
ntask.setParameterValue("TCRevNum", sTcRevNum);
ntask.setParameterValue("TCType", sTcType);
//The ReportPath were you want to store the file on server(linux) test17.pdf is the name of your file. You can change this.
var outputfile = fileDir + "temp.pdf"; //***** test17.pdf you can change to your file name.
//This is the export options.. this will change when exporting to another format.
var options = new PDFRenderOption();
options.setOutputFileName(outputfile);
options.setOutputFormat("pdf");
ntask.setRenderOption(options);
ntask.run();
ntask.close();
The problem is that it generates the report two times when calling the report as a post call from withing a system. Now I know why it does this because it does the runandrender again. I just want it to run once and export to a pdf.
The Java wrapper service is what I would recommend. You can use the RunAndRenderTask then instead of separate RunTask and RenderTask.
Or you can use the Web Viewer Servlet and retrieve the PDF output as the HTTP response.
Anyway, it is the wrong approach if you try to call any of these tasks from Javascript inside the report itself.
See https://wiki.eclipse.org/Integration_Examples_(BIRT) for an examples of the Java API and https://www.eclipse.org/birt/documentation/integrating/viewer-usage.php for the viewer (you'll want to use /run in your URL).

Tableau Workbook won't appear in website when trying to embed with Javascript

So I've been able to successfully embed a workbook hosted on Tableau Server using the html embed code. I now want some more flexibility with which reports I'm displaying to certain users of the website so I'm moving to the Javascript API. Unfortunately the workbook now isn't loading.
I'm following the Basic Embed tutorial on Tableau's website: https://onlinehelp.tableau.com/current/api/js_api/en-us/JavaScriptAPI/js_api_sample_basic_embed.html
Here's my code:
function initViz() {
var placeholderDiv = document.getElementById('tableauPlaceholder');
var url = 'https://#########.#######.###/views/EnrollmentTool/EnrollmentChange'
var options = {
hideTabs: true,
onFirstInteractive: function () {
console.log("Run this code when the viz has finished loading.");
}
};
var viz = new tableau.Viz(placeholderDiv, url, options);
}
The onFirstInteractive log statement doesn't get called, so it seems that the viz isn't actually loading.
I discovered the issue, the API version I was importing into my HTML file was viz_v1.js.
I had to use tableau-2.min.js instead.

Generate a designed PDF report from a web application

I want to generate a PDF report from a web application. The PDF should contain charts (pie, bar), tables, different fonts and colors.
The server-side of the application is Java, the client-side is AngularJS (and of course CSS3 and HTML).
Two main options:
The client side will pass some parameters to the server, and the server will generate the PDF report, using a Java package. Then the report will be sent back to the client as a downloaded file.
The client will generate the report, using a JS package that converts HTML and CSS to PDF.
In the Java world, I've found for example iText and JFreeChart, like here. The problem here is that the design of charts look bad in the example, and I don't know if it can be changed to be designed by the style-guide I have (a design that can be done easily with CSS).
In the JS world, I've found for example html2canvas and pdfMake, like here. The problem here is that I'm not sure the conversion from HTML to canvas and then to PDF will work good in an Angular application. And I'm not sure it converts well complicated DOM elements, like charts in svg or canvas elements.
Do you have any experience with these packages? Do you know other recommended packages for this task, client or server?
Want to share my solution... I chose a client-side solution.
I started with jsPDF, but had some problems. For example, it was hard to convert tables with the style I want.
I chose pdfMake for the PDF generation, html2canvas for taking screenshots of complicated designed components, and canvg for conversion of d3js charts (svg charts) to canvas (pdfMake can add canvas as image to the document).
I wrote a function that gets the CSS class of the HTML root of the part I want to convert to PDF (remember it's a single-page application), and also gets a meta data of which HTML nodes (again, by their CSS classes) should be added to the PDF (and what type is the node - table/text/image/svg).
Then, with DOM traversing, I walked through the elements I want to add to the PDF, and handled each one by its type. Part of the code (the traversing and the switch-case by type):
$(htmlRootSelector).contents().each(function processNodes(index, element) {
var classMeta = getMetaByClass(element.className);
if (!classMeta) {
$(element).contents().each(processNodes);
return;
}
var pdfObj = {};
pdfObj.width = classMeta.width || angular.undefined;
pdfObj.height = classMeta.height || angular.undefined;
pdfObj.style = classMeta.style || angular.undefined;
pdfObj.pageBreak = classMeta.pageBreak || angular.undefined;
switch (classMeta.type) {
case 'text':
pdfObj.text = element.innerText;
pdfDefinition.content.push(pdfObj);
break;
case 'table':
var tableArray = [];
var headerArray = [];
var headers = $(element).find('th');
var rows = $(element).find('tr');
$.each(headers, function (i, header) {
headerArray.push({text: header.innerHTML, style: classMeta.style + '-header'});
});
tableArray.push(headerArray);
$.each(rows, function (i, row) {
var rowArray = [];
var cells = $(row).find('td');
if (cells.length) {
$.each(cells, function (j, cell) {
rowArray.push(i % 2 === 1 ? {text: cell.innerText, style: classMeta.style + '-odd-row'} : cell.innerText);
});
tableArray.push(rowArray);
}
});
pdfObj.table = {
widths: $.map(headers, function (d, i) {
return i === 0 ? 80 : '*';
}),
body: tableArray
};
pdfDefinition.content.push(pdfObj);
break;
case 'image':
html2CanvasCount++;
htmlToCanvas(element, pdfObj);
pdfDefinition.content.push(pdfObj);
break;
case 'svg':
svgToCanvas(element, pdfObj);
pdfDefinition.content.push(pdfObj);
break;
default:
break;
}
$(element).contents().each(processNodes);
});
This is the solution in general.
Hope it will help someone.

Converting multiple files into HTML (from Markdown)?

I'm currently working on a small project in which I want to convert couple (or more) Markdown files into HTML and then append them to the main document. I want all this to take place client-side. I have chose couple of plugins such as Showdown (Markdown to HTML converter), jQuery (overall DOM manipulation), and Underscore (for simple templating if necessary). I'm stuck where I can't seem to convert a file into HTML (into a string which has HTML in it).
Converting Markdown into HTML is simple enough:
var converter = new Showdown.converter();
converter.makeHtml('#hello markdown!');
I'm not sure how to fetch (download) a file into the code (string?).
How do I fetch a file from a URL (that URL is a Markdown file), pass it through Showdown and then get a HTML string? I'm only using JavaScript by the way.
You can get an external file and parse it to a string with ajax. The jQuery way is cleaner, but a vanilla JS version might look something like this:
var mdFile = new XMLHttpRequest();
mdFile.open("GET", "http://mypath/myFile.md", true);
mdFile.onreadystatechange = function(){
// Makes sure the document exists and is ready to parse.
if (mdFile.readyState === 4 && mdFile.status === 200)
{
var mdText = mdFile.responseText;
var converter = new showdown.Converter();
converter.makeHtml(mdText);
//Do whatever you want to do with the HTML text
}
}
jQuery Method:
$.ajax({
url: "info.md",
context: document.body,
success: function(mdText){
//where text will be the text returned by the ajax call
var converter = new showdown.Converter();
var htmlText = converter.makeHtml(mdText);
$(".outputDiv").append(htmlText); //append this to a div with class outputDiv
}
});
Note: This assumes the files you want to parse are on your own server. If the files are on the client (IE user files) you'll need to take a different approach
Update
The above methods will work if the files you want are on the same server as you. If they are NOT then you will have to look into CORS if you control the remote server, and a server side solution if you do not. This question provides some relevant background on cross-domain requests.
Once you have the HTML string, you can append to the whatever DOM element you wish, by simply calling:
var myElement = document.getElementById('myElement');
myElement.innerHTML += markdownHTML;
...where markdownHTML is the html gotten back from makeHTML.

Categories