how to create multiple pdf with jdbc or xml in java - java

I Have some values associated with id i want to print those values with respective id's in pdf format, values can be in database or in some variable , can anyone suggest me which way i should go... i have some ideas either i can save those values in database and can make a single xml file from database of all records and then divide each node with different different pdf or directly get the values from database and generate the pdf so please anyone suggest me ideas and ways also if you can refer some links then most welcome please try to help me here.....
public class PDFGenerator extends HttpServlet
{
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, java.io.IOException
{
try
{
Connection con = ConnectionManager.getConnection();
Statement st4= con.createStatement();
ResultSet rs1 = st4.executeQuery("select count(*) from salary");
while(rs1.next())
{
int p = Integer.parseInt(rs1.getString(1));
System.out.println("saurabh :" +p);
for(int q=1;q<=p;q++)
{
Document document=new Document();
PdfWriter.getInstance(document,new FileOutputStream("c:/temp/salary.pdf"));
document.open();
PdfPTable table = new PdfPTable(2);
table.addCell("eid");
table.addCell("salary");
Statement st3= con.createStatement();
ResultSet rs = st3.executeQuery("select * from salary where eid ='"+q+"'");
while(rs.next())
{
table.addCell(rs.getString("eid"));
table.addCell(rs.getString("salary"));
}
document.add(table);
document.close();
}
}
}
catch (Exception e)
{
System.out.println(e);
}
}}
please anyone help me here....its printing last row only because its dealing with same pdf and again values are getting over written so please anyone help me how to generate pdf with multiple names so i can store in the same folder... with different name ....

If you want to create PDF's from Java, this is covered pretty comprehensively in the following question
http://www.stackoverflow.com/questions/6118635/
Here's a tutorial for the iText Java PDF library. I've used this guys tutorials for several Java/Eclipse/Android related problems and find him to be thorough and easy to follow:
http://www.vogella.com/tutorials/JavaPDF/article.html

its already generating n number of pdf which is specified through results of rows
but not getting saved only last one is getting saved because its getting over written
so its working because i have to send the mail after getting generated one mail..
so here is solution...
for(int q=1;q<=p;q++)
{
Document document=new Document();
PdfWriter.getInstance(document,new FileOutputStream("c:/temp/salary.pdf"));
document.open();
PdfPTable table = new PdfPTable(2);
table.addCell("eid");
table.addCell("salary");
Statement st3= con.createStatement();
ResultSet rs = st3.executeQuery("select * from salary where eid ='"+q+"'");
while(rs.next())
{
table.addCell(rs.getString("eid"));
table.addCell(rs.getString("salary"));
}
document.add(table);
document.close();
}
}

Related

How to go about saving an image in blob format to MySQL in Java

For the purpose of a task I have to store an image into MySQL as a blob format (even though it would have been better and ideal to store the image path in the database and keep the image in a folder in localcopy).
So far I have researched and couldn't find any answer that could help me, this is what I have done so far
Soon as a button click, this will be fired:
empdao.insertImage(fis);
Image is populated on another even listener like this :
static FileInputStream fis = null;
static String path = null;
path = filechooser.getSelectedFile().getAbsolutePath();
File image = new File(path);
fis = new FileInputStream (image);
This code below takes care of adding it into the database.
public void insertImage(FileInputStream fis) throws SQLException {
Connection c = getConnection();
String query = "INSERT INTO Picture (picture) VALUES (?)";
System.out.println(query);
PreparedStatement pstmt = c.prepareStatement(query);
pstmt.setBinaryStream(1, fis);
pstmt.executeUpdate();
c.close();
}
However the problem is that I needed it to convert it as a blob and I am not sure how to, can someone help me or guide me on how to go about storing the chosen image as a blob field into MySQL.
Currently when it adds it into database I get java.io file input under the pictures column.
Suppose you have a table my_picures in MySQL with id INT PRIMARY KEY, name VARCHAR(255), and photo BLOB.
Then you can use the following Java code to insert a new picture as BLOB:
public class InsertPictureAsBlob {
public static void main(String[] args) throws Exception, IOException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager
.getConnection("jdbc:mysql://localhost/databaseName", "username", "password");
String INSERT_PICTURE = "INSERT INTO my_picures(id, name, photo) VALUES (?, ?, ?)";
conn.setAutoCommit(false);
File file = new File("myPhoto.png");
try (FileInputStream fis = new FileInputStream(file);
PreparedStatement ps = conn.prepareStatement(INSERT_PICTURE)) {
ps.setString(1, "001");
ps.setString(2, "name");
ps.setBinaryStream(3, fis, (int) file.length());
ps.executeUpdate();
conn.commit();
}
}
}
1) First off you are going to want to make sure you have a table created in your MySQL schema with a BLOB column type defined (BLOB, MEDIUMBLOB, LONGBLOB). Review the BLOB column types that are available in MySQL and select the appropriate size.
2) You are going to want to switch from using a Statement to a PreparedStatement.
String query = "INSERT INTO Pictures (Picture) VALUES (?)";
PreparedStatement pstmt = conn.prepareStatement(query);
3) You are currently passing in a FileInputStream to your method so you just need to use the setBinaryStream method on the PreparedStatement.
pstmt.setBinaryStream(1, fis);
4) Then perform the executeUpdate() on the PreparedStatement.
pstmt.executeUpdate();
Utilize the exception handling you have in your original code and perform appropriate cleanup of objects (database connection, prepared statements), similar to what you have in your original code.

Display images on a JSP page through a servlet

I am trying to display images in a Jsp page using Jstl, and image paths are passed on by a servlet. The Jsp page actually displays only one of the retrieved images and throws a NullPointerException.
The Jsp looks like this:
<c:forEach items="${images}" var="img">
<div class="col-md-3">
<img src="displayImg?imageId=${img.imageId}">
</div>
</c:forEach>
And servlet doGet method looks like this:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int imageId = Integer.parseInt(request.getParameter("imageId"));
Image img = imageDao.getImageById(imageId);
response.setContentType("image/" + img.getImageType());
File f = new File(img.getImagePath());
BufferedImage bi = ImageIO.read(f);
OutputStream out = response.getOutputStream();
ImageIO.write(bi, img.getImageType(), out);
out.close();
}
I can't understand why this servlet manages to serve one image and fails on others with a NullPointerException when the request parameter is correct. I have an impression like it is a concurrency issue because the Jsp displays arbitrary image.
Any help please?
Here is the DAO:
public Image getImageById(int imageId) {
String query = "SELECT * FROM images WHERE imageId=?";
Image img = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
connection = ConnectionManager.getConnection();
ps = connection.prepareStatement(query);
ps.setInt(1, imageId);
rs = ps.executeQuery();
if (rs.next()) {
img = new Image();
img.setImageId(rs.getInt("imageId")); //NPE thrown here
img.setImagePath(rs.getString("imagePath"));
img.setImageType(rs.getString("imageType"));
...
img.setDescription(rs.getString("description"));
img.setCreatedOn(rs.getTimestamp("createdOn"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rs);
close(ps);
close(connection); //Removed this and problem disappears
}
return img;
}
Solved!!
It is weird but I just avoided closing the connection to the database and all my images are displaying correctly with no errors. I guess closing the connection after every single DB access is problematic as it could not close at the exact time you want it to but maybe in the middle of another call to the DB. Now I wonder, not closing the connection at all is problematic too. What to do in that case?
Weird as imageId is used as column name in the query, and there is a record, rs.next().
Maybe it is not an int but long, or SQL VARCHAR.
Maybe MySQL was so overly clever to leave out imageId as this was specified in the WHERE?
Or somehow in this case you need to use rs.getInt("images.imageId").
img.setImageId(rs.getInt("imageId")); //NPE thrown here
could however be written (circumvented) as
img.setImageId(mageId);
I would check that there is no devious typo: í (accent), Cyrillic e (if you are East European) or tab char. Honestly said your code looks neat, but similar errors happen with much less neat code: ps, ps2, rs, rs2 as fields, playing havoc with concurrent uses and apt to typos.
BTW writing could be done faster with less memory resources:
Path path = Paths.get(img.getImagePath());
OutputStream out = response.getOutputStream();
Files.copy(path, out);
On the search for errors:
Investigating the error seems the only option:
ResultSetMetaData meta = rs.getMetaData();
int numberOfColumns = meta.getColumnCount();
for (int i = 1; i <= numberOfColumns; ++i) {
log(... i, meta.getColumnName(i), meta.getColumnLabel(i) ...);
}
Just read the stack trace:
at com.mysql.jdbc.ResultSetImpl.buildIndexMapping(ResultSetImpl.java:674)
at com.mysql.jdbc.ResultSetImpl.findColumn(ResultSetImpl.java:1029)
at com.mysql.jdbc.ResultSetImpl.getInt(ResultSetImpl.java:2566)
at be.kayiranga.daoImpl.ImageDaoImpl.getImageById(ImageDaoImpl.java:114)
So, the exception is thrown by
rs.getInt("imageId")
which means that there is no column named "imageId" in the result set.
You should never use select *. Use explicit column names, and use these explicit column names when getting data from the result set:
select imageId, imagePath, imageType, description, createdOn from ...
THis answer might not help you completely, as no one I believe understands what you are doing exactly. I am presuming you have a JSP page and a form inside, I can show you how to display the image as a string.
public showImage(){
BASE64Encoder base64Encoder = new BASE64Encoder();
// your method to retreive the image
if(image == null){
File imagePath = new File("/home/akshay/images.jpeg"); // display alternate image
try {
BufferedImage bufferedImage = ImageIO.read(imagePath);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", byteArrayOutputStream);
//Below person is the main object model, and String is the image in string
person.setProfilePhotoString("data:image/png;base64," + base64Encoder.encode(byteArrayOutputStream.toByteArray()));
} catch (IOException e) {
e.printStackTrace();
}
} else{
person1.setProfilePhotoString("data:image/png;base64," + base64Encoder.encode(person1.getProfilephoto()));
}
}
JSP page :
<form:form action="${showAction}" commandName="person">
<table>
<tr>
<td><img src= "${person.profilePhotoString}" height=100 width=100/>
</tr>
</table>
</form>

JSP: "getOutputStream() has already been called for this response" get exception while display image on screen

I am getting exception while fatch image from database and display image on screen. Please help me to solve this error..
int questionid ;
Connection conn = null;
conn= new DBFunction().getconnect();
Statement stmt = conn.createStatement();
questionid=4;
try
{
conn.setAutoCommit (false);
// get the image from the database
Blob img ;
byte[] imgData = null ;
String req = "Select img From questionlist Where queid = " + questionid ;
ResultSet rset = stmt.executeQuery ( req );
while (rset.next ())
{
img = rset.getBlob("img");
imgData = img.getBytes(1,(int)img.length());
}
// display the image
response.reset();
response.setContentType("image/gif");
OutputStream o = response.getOutputStream();
o.write(imgData);
o.flush();
o.close();
}
catch (Exception e)
{
e.printStackTrace();
}
Let me know where am i wrong ?
It is not the better practice to write the java codes inside jsp as jsp calls printWriter by default. Scriptlets are not advised over decades . try moving the code into a java file , preferably a servlet.
Also it is not better option to store images into Database , try to use the diskspace instead. As far as your question try out.clear()
see How to avoid Java code in JSP files?

Uploading file from Struts/JSP into PostgreSQL large objects ("lo"/"oid") in the DB

I have an application that uses PostgreSQL, JSP and the STRUTS Framework
I want to insert a file into a table in PostgreSQL using the OID type, so it's stored as a large object in the database.
My table definition is this one:
CREATE TABLE mensaje
(
id serial NOT NULL,
file oid,
CONSTRAINT pk_mensaje PRIMARY KEY (id)
)
WITH (
OIDS=TRUE
);
ALTER TABLE mensaje
OWNER TO postgres;
Anybody know an example of how the Action, the ActionForm and the .jsp should be?
If not, is there any other example that explains how to do it without using the OID type?
This is a two step process to solve the problem:
File upload using Struts 2
PostgreSQL Java tutorial, check the Writing images section.
Additional note: Once the file has been received in your Action, you should use the byte array data to save it in your OID field.
From your comment, this should be the way in Struts 1.x
In the JSP
<html:form action="fileUploadAction" method="post" enctype="multipart/form-data">
File : <html:file property="upload" />
<br />
<html:submit />
</html:form>
In your action class
YourForm uploadForm = (YourForm) form;
FormFile file = null;
try {
file = uploadForm.getFile();
//FormFile#getFileData() returns the byte array containing the file data
//You can use it to save the file in your database and other things you want/need
int id = 9001; //assuming this is a valid id in the mensaje table
MensajeService mensajeService = new MensajeService();
mensajeService.saveFile(id, file.getFileData());
} catch (Exception e) {
//log the errors for maintenance purposes (bugs, fixes, etc)
}
The MensajeService class will connect to your Postgre database and save the file
public class MensajeService {
public MensajeService() {
}
public void saveFile(int id, byte[] fileData) throws SQLException {
//this is a very simple skeleton, you have to adapt this to
//your needs, the way you're connecting to dabatase, etc...
Connection con = null;
PreparedStatement pstmt = null;
try {
con = ... //get the connection to your postgre db
//Initialize a new transaction
con.setAutoCommit(false);
// Get the Large Object Manager to perform operations with
LargeObjectManager lobj = ((org.postgresql.PGConnection)conn)
.getLargeObjectAPI();
// Create a new large object
int oid = lobj.create(LargeObjectManager.READ | LargeObjectManager.WRITE);
// Open the large object for writing
LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE);
//in the provided example, the code shows a way to get the byte array data
//from the file (using the File and FileInputStream classes)
//you don't need all that because you already have the byte array (good!)
//so you only write the binary data in your LargeObject (OID) object
obj.write(fileData);
//creating the SQL statement to insert the OID
String sql = "INSERT INTO mensaje VALUES (?, ?)";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, id);
ps.setInt(2, oid);
//
pstmt.setBinaryStream(2, fin, (int) img.length());
//saving the file
pstmt.executeUpdate();
//closing the transaction successfully
con.commit();
} catch (SQLException e) {
//error in the transaction, start a rollback
if (con != null) {
con.rollback();
}
throw e;
} finally {
//don't forget to free the resources after using them
pstmt.close();
con.close();
}
}
}
Struts 1 code adapted from: Uploading a file in struts1.
PostreSQL code adapted from here.

xhtmlrenderer creating PDFs of length 0

I am new to org.xhtmlrenderer.pdf.ITextRenderer and have this problem:
The PDFs that my test servlet streams to my Downloads folder are in fact empty files.
The relevant method, streamAndDeleteTheClob, is shown below.
The first try block is definitely not a problem.
The server spends a lot of time in the second try block. No exception thrown.
Can anyone suggest a solution to this problem or a good approach to to debugging it?
Can anyone point me to essentially similar code that really works?
Any help would be much appreciated.
res.setContentType("application/pdf");
ServletOutputStream out = res.getOutputStream();
...
private boolean streamAndDeleteTheClob(int pageid,
Connection con,
ServletOutputStream out) throws IOException, ServletException {
Statement statement;
Clob htmlpage;
StringBuffer pdfbuf = new StringBuffer();
final String pageToSendQuery = "SELECT text FROM page WHERE pageid = " + pageid;
// create xhtml file as a CLOB (Oracle large character object) and stream it into StringBuffer pdfbuf
try { // definitely no problem in this block
statement = con.createStatement();
resultSet = statement.executeQuery(pageToSendQuery);
if (resultSet.next()) {
htmlpage = resultSet.getClob(1);
} else {
return true;
}
final Reader in = htmlpage.getCharacterStream();
final char[] buffer = new char[4096];
while ((in.read(buffer)) != -1) {
pdfbuf.append(buffer);
}
} catch (Exception ex) {
out.println("buffering CLOB failed: " + ex);
}
// create pdf from StringBuffer
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(pdfbuf.toString())));
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(doc, null);
renderer.layout();
renderer.createPDF(out);
out.close();
} catch (Exception ex) {
out.println("streaming of pdf failed: " + ex);
}
deleteClob(con, pageid);
return false;
}
Using the DocumentBuilder.parse this way will try to resolve the DTD referenced in the XHTML page. It takes a really long time. The easyest way to aviod that if you are using the Flying Saucer (xhtmlrenderer), is to create the document this way:
Document myDocument = XMLResource.load(myInputStream).getDocument();
Note that you can use XMLResource.load with a Reader too.
Two things I can think of.
1) If the iText document is not closed, it'll be empty. Looks like renderer.finish() will work, but createPDF(out) should do that already.
2) If there are no pages, you could get an empty doc as well... so an empty input could result in a 0-byte PDF.
3) You might be getting a perfectly valid PDF that's not being streamed properly. Try writing to a ByteArrayOutputStream and checking the length there.
4) An almost fanatical dedication to the Pope!

Categories

Resources