Generate png/jpeg image of Primefaces Charts in backing bean? - jsf-2

I am using Primefaces 3.1.1 charts in my application, there is no problem generating charts in JSF page, but I'm trying to find out if it's possible to generate image (png or jpeg) for the charts so that I can insert these images into an Excel file (Apache POI) in java.
I know the latest Primefaces version 3.4.1 has an Export Chart feature, but the generated image only occurs at the client side (it's jqPlot). But I need it on the server side.
Currently we are using jFreeChart in the backing bean for this purpose, so the charts in browser looked very different from the charts in Excel. We are trying to find out whether by upgrading to Primefaces 3.4.1 can give us the option to make the charts in browser and the charts in Excel looked the same? Or is there another way of doing this?
Using mojarra-2.1.3-FCS if this is a concern.

As in the accepted answer provided by Daniel, Primefaces' charts are not available at the server side. I add an answer here only to show a possible workaround.
At the client side, we assign the base64 PNG encoded string to a hidden field value, an example modified from Primefaces demo source code for export charts:
<h:form id="hform">
<p:lineChart value="#{testBean.linearModel}" legendPosition="e"
zoom="true" title="Linear Chart" minY="0" maxY="10"
style="width:500px;height:300px" widgetVar="chart" />
<p:commandButton id="exp" value="Export" icon="ui-icon-extlink"
onclick="exportChart();"
actionListener="#{testBean.submittedBase64Str}" />
<h:inputHidden id="b64" value="#{testBean.base64Str}" />
<script type="text/javascript">
function exportChart() {
// exportAsImage() will return a base64 png encoded string
img = chart.exportAsImage();
document.getElementById('hform:b64').value = img.src;
}
</script>
</h:form>
At the backing bean, we need to decode the string, a simple example as below:
public void submittedBase64Str(ActionEvent event){
// You probably want to have a more comprehensive check here.
// In this example I only use a simple check
if(base64Str.split(",").length > 1){
String encoded = base64Str.split(",")[1];
byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(encoded);
// Write to a .png file
try {
RenderedImage renderedImage = ImageIO.read(new ByteArrayInputStream(decoded));
ImageIO.write(renderedImage, "png", new File("C:\\out.png")); // use a proper path & file name here.
} catch (IOException e) {
e.printStackTrace();
}
}
}
The PNG file is now stored in the server, and you can continue to make use of that file in other parts of your codes.

As you already know Primefaces uses the jqPlot plugin to generate the charts , Since jqPlot is a jquery client side plugin it cannot generate anything on the server side , its a jquery plugin and not some server side api (jar)
So the answer is No :/
You might consider using some other server side chart generator (look at the links below) that will generate a better looking charts
13. Are there other "open source" chart libraries? (at the buttom)
What is the best open-source java charting library? (other than jfreechart)

Related

Printing from a Xamarin.Forms app

I'm all new to Xamarin and I'm currently working on a sample or a "prove of concept" app using Xamarin.Forms.
I'm supposed to perform a print task from this app though I'm not at this point sure what to print yet (the screen, content of a label, a file etc.).
Either way, what is the easiest way to print from a Xamarin.Forms app?
(current target is primarily Android 4.4+).
I hope this isn't too complicated :)
EDIT:
Ok let me just update this post as the original text might be a bit ambitious/vague.
I have a Xamarin.Forms project (+ an Android part) and I have some HTML available in the XF part of the project that I need to get into a WebView and print it.
From what I understand, the thing with the WebView has to be done on the Android part of the project due to the fact that this is where the printing will be handled.
I was hoping this could be done from code since I don't really need to display the WebView, just print it's content.
The Android part of the project has only the MainActivity and no layouts or XAML files.
I don't know where to add the WebView or how to access it (other than DependecyService seems to be a buzz word here) so I'm kinda stuck here.
I'm thinking that this task should be rather trivial to someone with a little more Xamarin experience than me.
Every platform XF supports has it's own mechanism for printing. XF does not provide any abstractions for printing in a cross-platform manner. You will need to write printing logic for each layer and expose it to XF using DependencyService (or some other DI engine).
Here is a good example, of course, using dependency service:
https://codemilltech.com/xamarin-forms-e-z-print/
I so wanted to do this but it was too hard. Finally built it into Forms9Patch - a MIT licensed open source project.
Verifying that Printing is available
Before printing, you should verify that printing is available on your device. To do so, call:
if (Forms9Patch.PrintService.CanPrint)
{
// do the printing here
}
Print the contents of a Xamarin.Forms.WebView
using Forms9Patch;
...
var myWebView = new Xamarin.Forms.WebView
myWebView.Source = new HtmlWebViewSource
{
Html = "some HTML text here"
};
...
myWebView.Print("my_print_job_name");
Note that your WebView does not have to be attached to a Layout. This allows you to Print without having to display the WebView in your app’s UI.
Printing an HTML string
using Forms9Patch;
...
var myHtmlString = #"
<!DOCTYPE html>
<html>
<body>
<h1>Convert to PNG</h1>
<p>This html will be converted to a PNG, PDF, or print.</p>
</body>
</html>
";
...
myHtmlString.Print("my_print_job_name");
PLEASE NOTE: iOS sometimes places the page breaks in weird places. I have a StackOverflow Bounty on why this happens and how to fix it.
Using EmbeddedResource as a source for a Xamarin.Forms.WebView
This is sort of an experimental feature I’ve built that I’ve found it useful. As such the documentation is sparse. It allow you to put HTML content in a folder in your app’s EmbeddedResources folder and then use it as a source for a WebView. A much nicer solution than using platform specific approach provided by Xamarin. It also supports putting all of the HTML content into a zip file. Please take a look at the source code to see how it works.
You can handle the printing of lists/ invoices .. with the xfinium pdf component from xamarin componentstore. With that you create your _pdffile and then call the following method which starts the adobereader from where you can select a printer (in my case google cloudprint)
public void printPdfToCloud(string _pdffile)
{
try
{
var saveto = System.IO.Path.Combine(Android.OS.Environment.ExternalStorageDirectory.ToString(), "YourApp/"+_pdffile);
string file_path = saveto;
if (System.IO.File.Exists(file_path))
{
Android.Net.Uri pdfFile = Android.Net.Uri.FromFile(new Java.IO.File(file_path));
Intent pdfIntent = new Intent(Intent.ActionView);
pdfIntent.SetPackage("com.adobe.reader");
pdfIntent.SetDataAndType(pdfFile, "application/pdf");
pdfIntent.SetFlags(ActivityFlags.NoHistory);
StartActivity(pdfIntent);
}else
{
// give a note that the file does not exist
}
}
catch (Exception E)
{
// Do some Error dialog
}
}

Highcharts: how to export several charts from the browser?

I have a page and there are four line charts on it. By having
exporting: {
enabled: false
}
I am able to see a Highcharts-generated export dropdown with options such as Download as PDF on each chart. These export options do not involve any access to the server. This is a pure client-side solution.
I wonder whether there is any way to use Javascript in the browser that allows me to export all charts on the page in a single PDF document?
Thanks and regards.
Well, I hate to be the one to break this to you but one clarification needs to be made, the default export options aren't really pure client-side. They leverage highcharts' own exporting server, one can override the exporting server's url using the exporting.url configuration option
url: String
The URL for the server module converting the SVG string to an image format.
By default this points to Highslide Software's free web service. Defaults to http://export.highcharts.com.
You may want to read their disclaimer & privacy statement & read more about the export module here
You can consider setting up your own exporting server, and override the export function to send SVG of all the charts on your page and do the stitching on the server side and send back the image.
exporting: {
buttons: {
contextButton: {
menuItems: [{
text: 'Export All Charts',
onclick: function() {
var allCharts=Highcharts.charts;
var svgArray=[];
for(var i=0;i<Highcharts.charts.length;i++){
svgArray[]=Highcharts.charts[i].getSVG();
}
// ... Post svgArray to your exporting server
}
}]
}
}
}
Having said that, modern browsers do support saving content of HTML5 canvas elements, check this jsFiddle that uses canvg library to export a single chart. P.S. This isn't the default behavior of highcharts

Render PDF in browser using Primefaces 3.4

Is it possible render a PDF object using Primeface 3.4 and DefaultStreamedContent? This used to work for us in Primefaces 2.2:
Backing Bean:
streamedDoc = new DefaultStreamedContent(pdfStream, "application/pdf");
...
public StreamedContent getStreamedDoc() {
return streamedDoc;
}
view:
<object id="embeddedPDF"
data="?primefacesDynamicContent=confirmForm.streamedDoc#toolbar=0?docId=456"
type="application/pdf"
width="100%"
height="1610px"/>
But after upgrading to 3.4, the PDF doesn't get rendered. We don't get an exception. We simply get this Abode Reader error in the browser:
Adobe Reader could not open 'A9RE0BF.tmp' because it is either not a supported file type or because the file has been damaged. (for example, it was sent as an email attachment and wasn't correctly encoded)."
Any ideas?
What about using the primefaces lightbox and the media components?
http://www.primefaces.org/showcase/ui/multimedia/media.xhtml
http://www.primefaces.org/showcase/ui/overlay/lightBox.xhtml
You can see the PDF inside the lightBox, I think it's more elegant.
Anyway just with the media one you can solve your problem I guess.
Regards.

How do I save the origin html file with Apache Nutch

I'm new to search engines and web crawlers. Now I want to store all the original pages in a particular web site as html files, but with Apache Nutch I can only get the binary database files. How do I get the original html files with Nutch?
Does Nutch support it? If not, what other tools can I use to achieve my goal.(The tools that support distributed crawling are better.)
Well, nutch will write the crawled data in binary form so if if you want that to be saved in html format, you will have to modify the code. (this will be painful if you are new to nutch).
If you want quick and easy solution for getting html pages:
If the list of pages/urls that you intend to have is quite low, then better get it done with a script which invokes wget for each url.
OR use HTTrack tool.
EDIT:
Writing a your own nutch plugin will be great. Your problem will get solved plus you can contribute to nutch by submitting your work !!! If you are new to nutch (in terms of code & design), then you will have to invest lot of time building a new plugin ... else its easy to do.
Few pointers for helping your initiative:
Here is a page which talks about writing own nutch plugin.
Start with Fetcher.java. See lines 647-648. That is the place where you can get the fetched content on per url basis (for those pages which got fetched successfully).
pstatus = output(fit.url, fit.datum, content, status, CrawlDatum.STATUS_FETCH_SUCCESS);
updateStatus(content.getContent().length);
You should add code right after this to invoke your plugin. Pass content object to it. By now, you would have guessed that content.getContent() is the content for url you want. Inside the plugin code, write it to some file. Filename should be based on the url name else it will be difficult to work with that. Url can be obtained by fit.url.
You must do modifications in run Nutch in Eclipse.
When you are able to run, open Fetcher.java and add the lines between "content saver" command lines.
case ProtocolStatus.SUCCESS: // got a page
pstatus = output(fit.url, fit.datum, content, status, CrawlDatum.STATUS_FETCH_SUCCESS, fit.outlinkDepth);
updateStatus(content.getContent().length);'
//------------------------------------------- content saver ---------------------------------------------\\
String filename = "savedsites//" + content.getUrl().replace('/', '-');
File file = new File(filename);
file.getParentFile().mkdirs();
boolean exist = file.createNewFile();
if (!exist) {
System.out.println("File exists.");
} else {
FileWriter fstream = new FileWriter(file);
BufferedWriter out = new BufferedWriter(fstream);
out.write(content.toString().substring(content.toString().indexOf("<!DOCTYPE html")));
out.close();
System.out.println("File created successfully.");
}
//------------------------------------------- content saver ---------------------------------------------\\
To update this answer -
It is possible to post process the data from your crawldb segment folder, and read in the html (including other data nutch has stored) directly.
Configuration conf = NutchConfiguration.create();
FileSystem fs = FileSystem.get(conf);
Path file = new Path(segment, Content.DIR_NAME + "/part-00000/data");
SequenceFile.Reader reader = new SequenceFile.Reader(fs, file, conf);
try
{
Text key = new Text();
Content content = new Content();
while (reader.next(key, content))
{
System.out.println(new String(content.GetContent()));
}
}
catch (Exception e)
{
}
The answers here are obsolete. Now, it is simply possible to get the plain HTML-files with nutch dump. Please see this answer.
In apache Nutch 2.3.1
You can save the raw HTML by edit the Nutch code firstly run the nutch in eclipse by following https://wiki.apache.org/nutch/RunNutchInEclipse
After you finish ruunning nutch in eclipse edit file FetcherReducer.java , add this code to the output method, run ant eclipse again to rebuild the class
Finally the raw html will added to reportUrl column in your database
if (content != null) {
ByteBuffer raw = fit.page.getContent();
if (raw != null) {
ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(raw.array(), raw.arrayOffset() + raw.position(), raw.remaining());
Scanner scanner = new Scanner(arrayInputStream);
scanner.useDelimiter("\\Z");//To read all scanner content in one String
String data = "";
if (scanner.hasNext()) {
data = scanner.next();
}
fit.page.setReprUrl(StringUtil.cleanField(data));
scanner.close();
}

Display Images From a file System using Richfaces + Spring Webflow

I am not able to display images from the file system in the xhtmls using <h:graphicImage> tag. I am using Spring webflow 2.0 and Richfaces 3.3.3
Should I write a separate servlet to serve the images from the file system ?
I looked into <a4j:mediaOutput> tag . Can I use this ? since createContent requires us to specify a method that will be used for content creating. I am unsure if we can use the flow variables/beans to execute methods in the tag.
You can always fetch the images placing under Web Pages folder
<h:graphicImage url="#{facesContext.externalContext.requestContextPath}\your_img_path_under_Web_pages" id="img" />
If you use <a4j:mediaOutput> tag, then yes you should give method in createContent which will draw the image.
<a4j:mediaOutput element="img" createContent="#{serviceBean.method}" value="#{dataBean}" mimeType="image/jpg" />
public void userImage(OutputStream out, Object data) throws IOException {/*your method body*/}

Resources