I'm looking for a solution to create reports using JasperReports for my application. I found some examples but still could not make it work. I'm using Vaadin7
I'm trying this
public class Report {
public Report(){
createShowReport();
}
private void createShowReport(){
final Map map = new HashMap();
StreamResource.StreamSource source = new StreamResource.StreamSource() {
public InputStream getStream() {
byte[] b = null;
try {
b = JasperRunManager.runReportToPdf(getClass().getClassLoader().getResourceAsStream("br/ind/ibg/reports/report3.jasper"), map, new JREmptyDataSource());
} catch (JRException ex) {
ex.printStackTrace();
}
return new ByteArrayInputStream(b);
}
};
StreamResource resource = new StreamResource(source, "report3.pdf");
resource.setMIMEType("application/pdf");
VerticalLayout v = new VerticalLayout();
Embedded e = new Embedded("", resource);
e.setSizeFull();
e.setType(Embedded.TYPE_BROWSER);
v.addComponent(e);
Window w = getWindow();
w.setContent(v);
UI.getCurrent().addWindow(w);
}
private Window getWindow(){
Window w = new Window();
w.setSizeFull();
w.center();
return w;
}
}
Any idea ?
Problem seems to be on the JasperPrint printer = JasperFillManager.fillReport(file, parametros,dados); line.
Make sure that your report is found (file is not null).
In order to show the report, what I usually do is put the resulted pdf in a stream, then create a streamResource with mimeType='application\pdf' and use window.open(resource) to show it.
Example:
StreamResource.StreamSource source = new StreamResource.StreamSource() {
public InputStream getStream() {
byte[] b = null;
try {
b = JasperRunManager.runReportToPdf(getClass().getClassLoader().getResourceAsStream("reports/report3.jasper"), map, con);
} catch (JRException ex) {
ex.printStackTrace();
}
return new ByteArrayInputStream(b);
}
};
StreamResource resource = new StreamResource(source, "report3.pdf", getApplication());
resource.setMIMEType("application/pdf");
getApplication().getMainWindow().open(resource, "_new");
Related
I have implemented html to pdf conversion using openhtmltopdf and I use it in Struts 2 action and it works very well. However, in the case of very large data, e.g. the html data is > 3Mb (pdf file ~1.6Mb) when I test it with JMeter for 50 hits the application crashes with message java.lang.OutOfMemoryError: Java heap space.
If I increase the java limit with the -Xmx option I just get some extra hits
The code i use is like this:
First clean html
public class HtmlToXhtmlConverterHTMLCleaner2 extends AbstractHtmlToXhtmlConverter
implements IHtmlToXhtmlConverter {
public HtmlToXhtmlConverterHTMLCleaner2(String htmlData) {
super(htmlData);
}
#Override
public void convert() {
final HtmlCleaner cleaner = new HtmlCleaner();
CleanerProperties cleanerProperties = cleaner.getProperties();
cleanerProperties.setAdvancedXmlEscape(true);
cleanerProperties.setOmitXmlDeclaration(true);
cleanerProperties.setOmitDoctypeDeclaration(false);
cleanerProperties.setTranslateSpecialEntities(true);
cleanerProperties.setTransResCharsToNCR(true);
cleanerProperties.setRecognizeUnicodeChars(true);
cleanerProperties.setIgnoreQuestAndExclam(true);
cleanerProperties.setUseEmptyElementTags(false);
cleanerProperties.setPruneTags("script");
final XmlSerializer xmlSerializer = new PrettyXmlSerializer(cleanerProperties);
try {
final TagNode rootTagNode = cleaner.clean(htmlData);
this.xhtmlData = xmlSerializer.getAsString(rootTagNode);
} catch (Exception ex) {
ex.printStackTrace();
}
}
then convert cleaned html to pdf
public class PDFConverterHtmlToPdf extends AbstractPDFConverter implements IPDFConverter {
ByteArrayOutputStream psfData;
public PDFConverterHtmlToPdf(String xhtmlData, String cssFile) {
super();
this.xhtmlData = xhtmlData;
this.cssFile = cssFile;
}
#Override
public void convert() {
pdfData = new ByteArrayOutputStream();
try {
// There are more options on the builder than shown below.
PdfRendererBuilder builder = new PdfRendererBuilder();
if(cssFile != null && cssFile.length() > 0){
builder.withHtmlContent(xhtmlData, cssFile);
} else {
builder.withHtmlContent(xhtmlData, "");
}
builder.toStream(pdfData);
builder.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
then send data from strus2 action to request
private void buildPdfContent(String htmlContent) {
String pdfConverterCssFile = "http://localhost:8080/DocumentConverterApi/css/htmlToPdf.css";
PDFConverterHelp pdfConverterHelp = new PDFConverterHelp("demo.pdf",
htmlContent, pdfConverterCssFile);
pdfConverterHelp.build();
inputStream = new ByteArrayInputStream(pdfConverterHelp.getPDFFile().toByteArray());
pdfConverterHelp.closePdfData();
contentDisposition = "inline;filename=\"" + "demo.pdf\"";
}
I'm doing something wron?
Is there any other way to implement it without the risk of crashing the application?
I have created a upload button, or upload buttons with Vaadin 14. Works like a charm. Perfect. But how do I access the images I uploaded? I have tried to read the tutorials on Vaadin's web page, but they only show the example I have post below. Not how to access the picture. I want to get all the pixels in a matrix form and turn them all into 0..255 gray scale.
Question:
Do you know what method to use to get the images, when I have upload or upload the pictures with this code?
#Data
public class PictureUpload {
private Upload upload;
public PictureUpload() {
// Add picture uploader
upload = new Upload();
addPictureUploader();
}
private void addPictureUploader() {
Div output = new Div();
MultiFileMemoryBuffer buffer = new MultiFileMemoryBuffer();
upload.setReceiver(buffer);
upload.setAcceptedFileTypes("image/jpeg", "image/png", "image/gif");
upload.addSucceededListener(event -> {
Component component = createComponent(event.getMIMEType(), event.getFileName(), buffer.getInputStream(event.getFileName()));
showOutput(event.getFileName(), component, output);
});
}
private Component createComponent(String mimeType, String fileName, InputStream stream) {
if (mimeType.startsWith("text")) {
return createTextComponent(stream);
} else if (mimeType.startsWith("image")) {
Image image = new Image();
try {
byte[] bytes = IOUtils.toByteArray(stream);
image.getElement().setAttribute("src", new StreamResource(fileName, () -> new ByteArrayInputStream(bytes)));
try (ImageInputStream in = ImageIO.createImageInputStream(new ByteArrayInputStream(bytes))) {
final Iterator<ImageReader> readers = ImageIO.getImageReaders(in);
if (readers.hasNext()) {
ImageReader reader = readers.next();
try {
reader.setInput(in);
image.setWidth(reader.getWidth(0) + "px");
image.setHeight(reader.getHeight(0) + "px");
} finally {
reader.dispose();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
Div content = new Div();
String text = String.format("Mime type: '%s'\nSHA-256 hash: '%s'", mimeType, MessageDigestUtil.sha256(stream.toString()));
content.setText(text);
return content;
}
private Component createTextComponent(InputStream stream) {
String text;
try {
text = IOUtils.toString(stream, StandardCharsets.UTF_8);
} catch (IOException e) {
text = "exception reading stream";
}
return new Text(text);
}
private void showOutput(String text, Component content, HasComponents outputContainer) {
HtmlComponent p = new HtmlComponent(Tag.P);
p.getElement().setText(text);
outputContainer.add(p);
outputContainer.add(content);
}
}
Update:
I did some test with Mr. Lund's example code below in the comments. It seems that I have trouble to show a picture with this code:
#Data
public class LoadExportTemplate {
private VerticalLayout subjectCounterExportButtonUploaders;
public LoadExportTemplate() {
subjectCounterExportButtonUploaders = new VerticalLayout();
Upload pictureUpload = new PictureUpload().getUpload();
Div output = new PictureUpload().getOutput();
subjectCounterExportButtonUploaders.add(pictureUpload, output);
}
}
Where I insert the subjectCounterExportButtonUploaders with this MainView code. I can't see the picture when I upload it.
#Route("")
#Viewport("width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes, viewport-fit=cover")
#PreserveOnRefresh
public class MainView extends AppLayout {
/**
*
*/
private static final long serialVersionUID = 1L;
public MainView() {
// Get the components
VerticalLayout buildPredictValidateTemplate = new BuildPredictValidateTemplate().getBuildButtonPredictButtonValidateButtonTextArea();
VerticalLayout subjectCounterExportButtonUpload = new LoadExportTemplate().getSubjectCounterExportButtonUploaders();
// Create logo and drawer
Image barImage = new Image("img/barImage.png", "Fisherfaces Logo");
barImage.setHeight("55px");
addToNavbar(new DrawerToggle(), barImage);
// Create tabs and add listeners to them
Tab buildPredictValidate = new Tab("Build & Predict & Validate");
buildPredictValidate.getElement().addEventListener("click", e -> {
getContent().getChildren().forEach(component -> {
boolean visible = component.equals(buildPredictValidateTemplate);
component.setVisible(visible);
});
});
Tab loadExport = new Tab("Load & Export");
loadExport.getElement().addEventListener("click", e -> {
// Walk around from the bug
getContent().getChildren().forEach(component -> {
boolean visible = component.equals(subjectCounterExportButtonUpload);
component.setVisible(visible);
});
});
// Set the contents
setContent(new Div(buildPredictValidateTemplate, subjectCounterExportButtonUpload));
subjectCounterExportButtonUpload.setVisible(false);
// Add them and place them as vertical
Tabs tabs = new Tabs(buildPredictValidate, loadExport);
tabs.setOrientation(Tabs.Orientation.VERTICAL);
addToDrawer(tabs);
}
}
But this example works. Here I can see the picture when I upload it.
#Route(value = UploadView.ROUTE)
#PageTitle(UploadView.TITLE)
public class UploadView extends AppLayout{
/**
*
*/
private static final long serialVersionUID = 1L;
public static final String ROUTE = "upload";
public static final String TITLE = "Upload";
public UploadView() {
PictureUpload pictureUpload = new PictureUpload();
VerticalLayout vl = new VerticalLayout();
vl.add(pictureUpload.getUpload(),pictureUpload.getOutput());
setContent(vl);
}
}
Do you know why?
In the comments you clarified that all you want is to get the byte[] of the image after the upload. Here is how you could do that.
Variant 1: MultiFileMemoryBuffer
MultiFileMemoryBuffer buffer = new MultiFileMemoryBuffer();
upload.setReceiver(buffer);
upload.setAcceptedFileTypes("image/jpeg", "image/png", "image/gif");
upload.addSucceededListener(event -> {
byte[] imageBytes = IOUtils.toByteArray(buffer.getInputStream(event.getFileName()));
});
Variant 2: be your own Receiver interface
public class UploadView implements Receiver {
private FastByteArrayOutputStream outputStream;
private Upload upload;
private Button actualUploadButton;
public UploadView(){
upload = new Upload(this);
upload.setAcceptedFileTypes("image/jpeg", "image/png", "image/gif");
upload.addSucceededListener(event -> {
// uploaded file is now in outputStream
byte[] newImageBytes = outputStream.toByteArray();
Notification.show("We have now got the uploaded images bytearray!");
});
upload.setMaxFiles(10);
actualUploadButton = new Button(getTranslation("upload-image"), VaadinIcon.UPLOAD.create());
actualUploadButton.setWidth("100%");
upload.setUploadButton(actualUploadButton);
add(upload);
}
#Override
public OutputStream receiveUpload(String s, String s1) {
return outputStream = new FastByteArrayOutputStream();
}
}
#Override
public String generateBrcodeForId(String Id) {
BarcodeUtil util = BarcodeUtil.getInstance();
BarcodeGenerator gen;
ByteArrayOutputStream byteArrayOutputStream = null;
try {
gen = util.createBarcodeGenerator(buildCfg("code128"));
OutputStream fout;
fout = new FileOutputStream("code128.jpg");
byteArrayOutputStream = new ByteArrayOutputStream();
int resolution = 200;
BitmapCanvasProvider canvas = new BitmapCanvasProvider(
fout, "image/jpeg", resolution, BufferedImage.TYPE_BYTE_BINARY, false, 0);
gen.generateBarcode(canvas, "12345678");
canvas.finish();
} catch (ConfigurationException | BarcodeException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
private static Configuration buildCfg(String type) {
DefaultConfiguration cfg = new DefaultConfiguration("barcode");
//Bar code type
DefaultConfiguration child = new DefaultConfiguration(type);
cfg.addChild(child);
//Human readable text position
DefaultConfiguration attr = new DefaultConfiguration("human-readable");
DefaultConfiguration subAttr = new DefaultConfiguration("placement");
subAttr.setValue("bottom");
attr.addChild(subAttr);
child.addChild(attr);
return cfg;
}
Have created a bar code using Barcode4j, Here its creating a image code128.jpg. Can I create a byte array instead Of creating an image in the filesystem and send that to the web service client.
Got the solution, solved it using ByteArrayOutputStream
#Override
public byte[] generateBarcodeForId(String Id) {
BarcodeUtil util = BarcodeUtil.getInstance();
BarcodeGenerator gen;
ByteArrayOutputStream bao = null;
try {
gen = util.createBarcodeGenerator(buildCfg("code128"));
OutputStream fout;
int resolution = 100;
bao = new ByteArrayOutputStream();
BitmapCanvasProvider canvas = new BitmapCanvasProvider(
bao, "image/jpeg", resolution, BufferedImage.TYPE_BYTE_BINARY, false, 0);
gen.generateBarcode(canvas, Id);
canvas.finish();
} catch (ConfigurationException | BarcodeException | IOException e) {
e.printStackTrace();
} finally {
try {
bao.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return bao.toByteArray();
}
private static Configuration buildCfg(String type) {
DefaultConfiguration cfg = new DefaultConfiguration("barcode");
//Bar code type
DefaultConfiguration child = new DefaultConfiguration(type);
cfg.addChild(child);
//Human readable text position
DefaultConfiguration attr = new DefaultConfiguration("human-readable");
DefaultConfiguration subAttr = new DefaultConfiguration("placement");
subAttr.setValue("bottom");
attr.addChild(subAttr);
child.addChild(attr);
return cfg;
}
I have a PDF in project location how to open pdf file
my project name is MyProject
My pdf is under project folder
MyProject\Pdf\test.pdf how to open my pdf file
I need to open pdf file in the project location
I have tried below code
final Button viewBtn= new Button("View Policy Schedule");
viewBtn.addClickListener( newButton.ClickListener() public void buttonClick(ClickEvent event) {
Window window = new Window();
window.setResizable(true);
window.setCaption("Claim Form Covering Letter PDF");
window.setWidth("800");
window.setHeight("600");
window.setModal(true);
window.center();
final String filepath = "Pdf//test.pdf";
File f = new File(filepath);
System.out.println(f.getAbsolutePath());
Path p = Paths.get(filepath);
String fileName = p.getFileName().toString();
StreamResource.StreamSource s = new StreamResource.StreamSource() {
/**
*
*/
private static final long serialVersionUID = 9138325634649289303L;
public InputStream getStream() {
try {
File f = new File(".");
System.out.println(f.getCanonicalPath());
FileInputStream fis = new FileInputStream(f);
return fis;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
};
StreamResource r = new StreamResource(s, fileName);
Embedded e = new Embedded();
e.setSizeFull();
e.setType(Embedded.TYPE_BROWSER);
r.setMIMEType("application/pdf");
e.setSource(r);
window.setContent(e);
UI.getCurrent().addWindow(window);
}
});
It's not working I have got a file not found exception
Move the PDF so you can read it from the classpath. If you are using Maven put it in src/main/resources. Otherwise put it in some package.
You can then read it using getResourcesAsStream() method of java.lang.class.
InputStream in = this.getClass().getResourcesAsStream("/test.pdf"); //classpath root
InputStream in = this.getClass().getResourcesAsStream("/my/package/name/test.pdf"); //from some package
Updated
final Button viewBtn= new Button("View Policy Schedule");
viewBtn.addClickListener( newButton.ClickListener()
public void buttonClick(ClickEvent event) {
Window window = new Window();
window.setResizable(true);
window.setCaption("Claim Form Covering Letter PDF");
window.setWidth("800");
window.setHeight("600");
window.setModal(true);
window.center();
StreamResource.StreamSource s = new StreamResource.StreamSource() {
public InputStream getStream() {
try {
return this.getClass().getResourcesAsStream("/test.pdf");
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
};
StreamResource r = new StreamResource(s, fileName);
Embedded e = new Embedded();
e.setSizeFull();
e.setType(Embedded.TYPE_BROWSER);
r.setMIMEType("application/pdf");
e.setSource(r);
window.setContent(e);
UI.getCurrent().addWindow(window);
}
});
I have written a code in java that help me to generate a pdf . I have used Itext libraries to generate it. This code also consists of database connectivity with postgres. I have used two jar files itextpdf-5.4.5.jar and postgresql-9.0-901.jar. But as i have mentioned that this code is in java. Now i want this code to work as service in my grails project. As i have read some documentaion of grails that grails service do not contain any database connectivity code.So kindly help me though i 'm new to grails. I don't need any plugins of grails.
FrameworkPDF.java
public class FrameworkPDF extends PostgresqlConnection{
/**
* #param args
*/
public static final String FILE = "E:/framework.pdf";
public static final int FRAMEWORK_ID = 650;
public static final String RESOURCE = "E:/images/logo.png";
public static final Font BOLD_UNDERLINED = new Font(FontFamily.TIMES_ROMAN, 18,
Font.BOLD);
public static final Font H2 = new Font(FontFamily.TIMES_ROMAN, 14, Font.BOLD |
Font.UNDERLINE);
public static final Font H3 = new Font(FontFamily.TIMES_ROMAN, 12, Font.BOLD);
public static final Font H4 = new Font(FontFamily.TIMES_ROMAN, 12, Font.BOLD |
Font.UNDERLINE);
public static void main(String[] args)
{
FrameworkPDF.createPdf(FILE,
FrameworkPDF.getFrameworkData(FRAMEWORK_ID),FRAMEWORK_ID,3);
}
public static void createPdf(String filename, String content, int frameworkId, int
level) {
Document document = new Document();
try
{
PdfWriter.getInstance(document, new FileOutputStream(filename));
document.open();
// Adding a java.awt.Image
java.awt.Image awtImage = Toolkit.getDefaultToolkit().createImage(RESOURCE);
Image img = com.itextpdf.text.Image.getInstance(awtImage, null);
img.scaleToFit(120, 250);
img.setAlignment(img.ALIGN_RIGHT);
document.add(img);
Paragraph p = new Paragraph();
p.add(new Chunk(content, BOLD_UNDERLINED));
document.add(p);
document.add(new LineSeparator(0.5f, 100, null, 0, -5));
Paragraph p1 = new Paragraph();
p1.add(new Chunk("\nCore Principles: ", H2));
document.add(p1);
int i=0;
ArrayList<String> cp = FrameworkPDF.getRubrics(662, 3);
Iterator<String> itr = cp.iterator();
while(itr.hasNext())
{
i++;
String s = itr.next();
Paragraph p2 = new Paragraph();
p2.add(new Chunk("\n".concat(String.valueOf(i)).concat(".
").concat(s), H3));
document.add(p2);
}
Paragraph p2 = new Paragraph();
p2.add(new Chunk("\nLevel wise rubrics: \n", H4));
document.add(p2);
i=1;
while(level > 0)
{
Paragraph p3 = new Paragraph();
p3.add(new Chunk("\nLevel ".concat(String.valueOf(i)), H3));
document.add(p3);
ArrayList<String> rub = FrameworkPDF.getRubrics(frameworkId, level);
Iterator<String> rubitr = rub.iterator();
while(rubitr.hasNext())
{
String s = rubitr.next();
Paragraph p4 = new Paragraph();
p4.add(new Chunk(s, H3));
document.add(p4);
}
level--;
i++;
}
document.add(createTable(countRatings(FRAMEWORK_ID)));
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (DocumentException e)
{
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
// step 5
document.close();
}
}
}
PostgresqlConnection.java
public class PostgresqlConnection {
public static String sql = null;
public static Connection conn= null;
public static Properties props = null;
public static String url = null;
public static Statement stmt = null;
public static ResultSet rs = null;
public static void connect()
{
url = "jdbc:postgresql://localhost/onet";
props = new Properties();
props.setProperty("user","postgres");
props.setProperty("password","password");
try
{
conn = DriverManager.getConnection(url, props);
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public static void close()
{
try
{
if(stmt!=null)
stmt.close();
}
catch(SQLException se2)
{
se2.printStackTrace();
}
try
{
if(rs!=null)
rs.close();
}
catch(SQLException se2)
{
se2.printStackTrace();
}
try
{
if(conn!=null)
conn.close();
}
catch(SQLException se)
{
se.printStackTrace();
}
}
}
You can put your existing java file to src/java in Grails Application and create a new service in service directory and call your method like :
FrameworkPDF.createPdf(FILE,FrameworkPDF.getFrameworkData(FRAMEWORK_ID),FRAMEWORK_ID,3);
from any method of service. And also add the jar dependency to your BuildConfig.groovy file like :
compile :"postgresql:postgresql:9.1-901.jdbc3"
compile :"com.itextpdf:itext-pdfa:5.4.5"
It should work.
If you want to use Grails DataSource then you can follow following step:
Remove the PostgresqlConnection class and you can enter your database connection details in DataSource.groovy. Once you have done with that, do following :
in your service and can code like below :
def dataSource
def sql = Sql.newInstance(dataSource)
def row = sql.firstRow("select fname, lname, email from person where id = ${personId}")
if (row) {
return [firstName: row.fname, lastName: row.lname, email: row.email]
}
I hope it should resolve you problem.
If you want to actually treat your java class as a bean (service), you could wire it up as such in the resources.groovy file.
beans = {
frameworkPdfService(your.package.FrameworkPDF){}
}
and then inject it into another service or controller in your app
public class MyService {
def frameworkPdfService
...
}