I'm using this within an application where writing to a file is not possible. The data is always in streams. I get the XLSX file in an inputstream and I would like to set a password and write it to an outputstream.
public void encrptXslxFile(InputStream inStream, OutputStream outStream){
POIFSFileSystem fs = null;
EncryptionInfo info = null;
OutputStream fos;
OPCPackage opc = null;
try {
info = new EncryptionInfo(EncryptionMode.agile);
Encryptor enc = info.getEncryptor();
enc.confirmPassword("coffee");
//inStream = new FileInputStream("C:\\ProjectWork\\Community\\excelfile.xlsx");
fs = new POIFSFileSystem();
opc = OPCPackage.open(inStream); //from parameter
OutputStream os = enc.getDataStream(fs);
opc.save(os);
os.close();
//fos = new FileOutputStream("C:\\ProjectWork\\Community\\excelfilepwd.xlsx");
//fs.writeFilesystem(fos);
//fos.close();
fs.writeFilesystem(outStream); // from parameter
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
While reading from the file and writing to the file, it encrypts fine. But if I use the function and then get the outputstream, and later write it, it creates a zero kb file.
Is this even possible?
I tested with the code below to makes sure the inputstream is good.
public void encrptXslxFile(InputStream inStream, OutputStream outStream){
try {
IOUtils.copy(inStream, outStream);
} catch (IOException e) {
e.printStackTrace();
}
}
I was able to write the outputstream to a file.
Since I cannot create files and POI internally uses files, I had to specifically set the temp directory for POI to use.
TempFile.setTempFileCreationStrategy(new TempFileCreationStrategy() {
#Override
public File createTempFile(String prefix, String suffix) throws IOException {
// check dir exists, make if doesn't
if(!fileTempDir.exists()){
fileTempDir.mkdir();
fileTempDir.deleteOnExit();
}
File newFile = File.createTempFile(prefix, suffix, fileTempDir);
return newFile;
}
#Override
public File createTempDirectory(String strPath) throws IOException {
if(!fileTempDir.exists()){
fileTempDir.mkdir();
fileTempDir.deleteOnExit();
return fileTempDir;
}else {
return Files.createTempDirectory(strPath).toFile();
}
}
});
This worked for me.
Facing a problem while implementing a java-ws service for downloading a pdf file from another webservice. Below is the piece of code for the same.decode() is used because of the webservice(this java code is invoking) is responding with encoded binary-base-64. I could see the PDF is downloaded in the given location but when i open with pdf reader, it says the file is corrupt. Could you please help me ?
public DownloadFileResponse DownloadResponseMapper(Header header, DownloadDocumentResponseType response){
DownloadFileResponse result = new DownloadFileResponse();
result.setHeader(header);
Status status = new Status();
status.setStatusCode(String.valueOf(String.valueOf(response.getStatus().getStatusCode())));
status.setStatusMessage(response.getStatus().getMessage());
result.setStatus(status);
if(String.valueOf(String.valueOf(String.valueOf(response.getStatus().getStatusCode()))) != "0") {
String qNameFile = FileExchange.getProperty("fileSystem.sharedLocation") + "/" + "result.pdf";
try {
byte[] fileContent = FileUtil.decode(response.getFile());
System.out.println(response.getFile());
FileUtil.writeByteArraysToFile(qNameFile, fileContent);
} catch (Exception e) {
_logger.info(e.getStackTrace());
}
// calculate the hash of the file using two algorithm SHA-256/SHA-512
List<FileHashType> hashes = FileUtil.calculateHash(result.getFile());
result.setFileHash(hashes);
}
return result;
}
public static void writeByteArraysToFile(String fileName, byte[] content) throws IOException {
File file = new File(fileName);
BufferedOutputStream writer = new BufferedOutputStream(new FileOutputStream(file));
writer.write(content);
writer.flush();
writer.close();
}
I have a requirement to convert XML to PDF document for that am using XSL - Apache FOP (Java). Am getting the below error The method newInstance(FopFactoryConfig) in the type FopFactory is not applicable for the arguments () for the below line
// create an instance of fop factory
FopFactory fopFactory = FopFactory.newInstance();
Please find my full java code:
public static void main (String args[])
{
// the XSL FO file
File xsltfile = new File("sample2.xsl");
// the XML file from which we take the name
StreamSource source = new StreamSource(new File("sample2.xml"));
// creation of transform source
StreamSource transformSource = new StreamSource(xsltfile);
// create an instance of fop factory
FopFactory fopFactory = FopFactory.newInstance(); // Error throwing in this line..
// a user agent is needed for transformation
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
// to store output
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
Transformer xslfoTransformer;
try
{
xslfoTransformer = getTransformer(transformSource);
// Construct fop with desired output format
Fop fop;
try
{
fop = fopFactory.newFop
(MimeConstants.MIME_PDF, foUserAgent, outStream);
// Resulting SAX events (the generated FO)
// must be piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing
try
{
// everything will happen here..
xslfoTransformer.transform(source, res);
// if you want to get the PDF bytes, use the following code
//return outStream.toByteArray();
// if you want to save PDF file use the following code
File pdffile = new File("Result.pdf");
OutputStream out = new java.io.FileOutputStream(pdffile);
out = new java.io.BufferedOutputStream(out);
FileOutputStream str = new FileOutputStream(pdffile);
str.write(outStream.toByteArray());
str.close();
out.close();
}
catch (TransformerException e) {
throw e;
}
}
catch (FOPException e) {
throw e;
}
}
catch (TransformerConfigurationException e)
{
throw e;
}
catch (TransformerFactoryConfigurationError e)
{
throw e;
}
}
private static Transformer getTransformer(StreamSource streamSource)
{
// setup the xslt transformer
net.sf.saxon.TransformerFactoryImpl impl =
new net.sf.saxon.TransformerFactoryImpl();
try {
return impl.newTransformer(streamSource);
} catch (TransformerConfigurationException e) {
e.printStackTrace();
}
return null;
}
Please find the below dependencies am using :
<!-- https://mvnrepository.com/artifact/org.apache.xmlgraphics/fop -->
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop</artifactId>
<version>2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.saxon/Saxon-HE -->
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>9.8.0-11</version>
</dependency>
Check the API documentation for your version of Apache FOP, I think you need to provide a base URI or a configuration file e.g.
FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
to set up the current working directory's URI as the base URI.
I am trying to add a function to my web app which lets the users download an excel file.
I'm trying to achieve this with the following code:
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) {
File file = new File("d:/test/test.xls");
response.setContentType("application/xls");
response.addHeader("Content-Disposition", "attachment; filename=test.xls");
response.setContentLength((int) file.length());
try {
FileInputStream fileInputStream = new FileInputStream(file);
OutputStream responseOutputStream = response.getOutputStream();
int bytes;
while ((bytes = fileInputStream.read()) != -1) {
responseOutputStream.write(bytes);
}
fileInputStream.close();
responseOutputStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I'm able to download the excel file with the above code, however the file is corrupted. If I open it with microsoft excel, I get a popup with the message:
"the file format and extension of don't match. the file could be corrupted or unsafe".
And the excel file is empty.
After running the code, the original file(d:/test/test.xls) gets also corrupted.
What am I doing wrong?
The official MIME type for Excel file .xls is application/vnd.ms-excel and for .xlsx is application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.
Also, I would suggest doing response.reset() prior to writing to the output stream and responseOutputStream.flush() (important) prior to closing the response.
Try below code :
File file = null;
InputStream in = null;
OutputStream outstream = null;
try {
response.reset();
in = new FileInputStream(file);
response.setContentType("application/vnd.ms-excel");
response.addHeader("content-disposition", "attachment; filename=data.xls");
outstream = response.getOutputStream();
IOUtils.copyLarge(in, outstream);
}
catch (Exception e) {
out.write("Unable to download file");
}finally {
IOUtils.closeQuietly(outstream);
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
if (file != null)
file.delete();
}
dont forgot to add apache commons-io-2.4 in your dependency
I have a html page with text, image and I am parsing the HTML content to iText to generate the PDF. In the generated PDF,Included images are not getting displayed and , only the text is getting displayed.
If I pass the absolute path like D:/Deiva/CRs/HTMLPage/article-101-horz.jpg then the image will get printed. But if I try to print the image from the server like
http://localhost:8085/content/dam/article-101-h1.jpg or http://www.google.co.in/intl/en_ALL/images/logos/images_logo_lg.gif
then it is not getting printed in the PDF.
NOTE: I am using itextpdf-5.2.1.jar to generate the PDF.
My HTML Code (Article.html):
<html>
<head>
</head>
<body>
<p>Generate PDF with image using iText.</p>
<img src="http://localhost:8085/content/dam/article-10-h1.jpg"></img>
<img src="http://www.google.co.in/intl/en_ALL/images/logos/imgs_logo_lg.gif"></img>
<img class="right horz" src="D:/Deiva/CRs/HTMLPage/article-101-horz.jpg"></img>
</body>
</html>
I am using the below java code for generating the PDF:
private void createPDF (){
String path = "D:/Deiva/Test.pdf";
PdfWriter pdfWriter = null;
//create a new document
Document document = new Document();
try {
//get Instance of the PDFWriter
pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(path));
//document header attributes
document.addAuthor("betterThanZero");
document.addCreationDate();
document.addProducer();
document.addCreator("MySampleCode.com");
document.addTitle("Demo for iText XMLWorker");
document.setPageSize(PageSize.LETTER);
//open document
document.open();
InputStream is = new FileInputStream("D:/Deiva/CRs/Oncology/Phase5/CR1/HTMLPage/Article.html");
// create new input stream reader
InputStreamReader isr = new InputStreamReader(is);
//get the XMLWorkerHelper Instance
XMLWorkerHelper worker = XMLWorkerHelper.getInstance();
//convert to PDF
worker.parseXHtml(pdfWriter, document, isr);
//close the document
document.close();
//close the writer
pdfWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Please suggest a solution to display the image in PDF.
Thanks in advance.
Deiva
I think you can do it easily using a Servlet for viewing the image. How to write a servlet for this is here
Here a sample dispatcher for you. Just edit the required places as needed
#Controller
public class ImageController extends DispatcherServlet {
private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
// Properties ---------------------------------------------------------------------------------
private String imagePath;
#RequestMapping(value="images/{imageId:.+}", method = RequestMethod.GET)
public #ResponseBody void getImage(#PathVariable String imageId,HttpServletRequest request, HttpServletResponse response){
String requestedImage = request.getPathInfo();
this.imagePath ="image path in server here";
if (requestedImage == null) {
// Do your thing if the image is not supplied to the request URI.
// Throw an exception, or send 404, or show default/warning image, or just ignore it.
try {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}catch(IOException ioException){
logger.error("error image path incorrect:{}", ioException);
} // 404.
return;
}
File image=null;
try {
image = new File(imagePath, URLDecoder.decode(imageId, "UTF-8"));
} catch (UnsupportedEncodingException unsupportedEncodingException) {
logger.error("error image can not decode:{}", unsupportedEncodingException);
}
// Check if file actually exists in filesystem.
if (!image.exists()) {
// Do your thing if the file appears to be non-existing.
// Throw an exception, or send 404, or show default/warning image, or just ignore it.
try {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}catch(IOException ioException){
logger.error("error image does not exists:{}", ioException);
} // 404.
return;
}
// Get content type by filename.
String contentType = "jpeg";
contentType="image/"+contentType;
// Init servlet response.
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(image.length()));
response.setHeader("Content-Disposition", "inline; filename=\"" + image.getName() + "\"");
// Prepare streams.
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
// Open streams.
try {
input = new BufferedInputStream(new FileInputStream(image), DEFAULT_BUFFER_SIZE);
} catch (FileNotFoundException e) {
logger.error("error creating file input stream to the image file :{}", e);
}
try {
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
} catch (IOException e) {
logger.error("error creating output stream to the http response :{}", e);
}
// Write file contents to response.
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
try {
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} catch (IOException e) {
logger.error("error writing the image file to outputstream :{}", e);
}
} finally {
// Gently close streams.
close(output);
close(input);
}
}
// Helpers (can be refactored to public utility class) ----------------------------------------
private void close(Closeable resource) {
if (resource != null) {
try {
resource.close();
} catch (IOException e) {
// Do your thing with the exception. Print it, log it or mail it.
logger.error("error closing resources:{}", e);
}
}
}
}
Here are some examples: https://developers.itextpdf.com/examples/xml-worker-itext5/html-images
htmlContext.setImageProvider(new AbstractImageProvider() {
public String getImageRootPath() { return "src/main/resources/html/"; }
});
If the HTML file you're parsing is stored in a directory that is different from the working directory, iText won't be able to create Image objects. We have to supply an implementation of the ImageProvider interface that tells iText what to do if an img tag is encountered. This interface has the following methods:
Image retrieve(final String src);
String getImageRootPath();
void store(String src, Image img);
void reset();
You can write your own class implementing these four methods, or you can subclass AbstractImageProvider. It is preferred to do the latter. XML Worker will use the store() method of the AbstractImageProvider class to cache all the Image objects that are encountered in a Map. These objects will be reused when the retrieve() method is called for an image with the same src. If you don't cache images, your PDF will be bloated. The same image bits and bytes will be written to the PDF more than once. The reset() method clears the cache; it is used when an ImageProvider is cloned. Finally, the getImageRootPath() method isn't implemented.
If the HTML file you're parsing is stored in a directory that is different from the working directory, iText won't be able to create Image objects. We have to supply an implementation of the ImageProvider interface that tells iText what to do if an img tag is encountered. This interface has the following methods:
You can write your own class implementing these four methods, or you can subclass AbstractImageProvider. It is preferred to do the latter. XML Worker will use the store() method of the AbstractImageProvider class to cache all the Image objects that are encountered in a Map. These objects will be reused when the retrieve() method is called for an image with the same src. If you don't cache images, your PDF will be bloated. The same image bits and bytes will be written to the PDF more than once. The reset() method clears the cache; it is used when an ImageProvider is cloned. Finally, the getImageRootPath() method isn't implemented. You have to implement it yourself, as is done in the following snippet:
to show image with Itext, you have to Changing the default configuration about Image Provider Like it :
i do it from http://demo.itextsupport.com/xmlworker/itextdoc/flatsite.html
public class HtmlToPDF1 {
public static void main(String ... args ) throws DocumentException, IOException {
FontFactory.registerDirectories();
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream("src/test/ressources/mypdf.pdf"));
document.open(); HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
htmlContext.setImageProvider(new AbstractImageProvider() {
public String getImageRootPath() {
return "/home/fallphenix/workspace/JAVA/JEE/testHTMLtoPDF/src/test/ressources/";
}
}); CSSResolver cssResolver =
XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
Pipeline<?> pipeline =
new CssResolverPipeline(cssResolver,
new HtmlPipeline(htmlContext,
new PdfWriterPipeline(document, writer)));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser p = new XMLParser(worker);
p.parse(new FileInputStream("src/test/ressources/other.html"));
document.close();
System.out.println("Done.");
}}
Try getting the image into a memory or byte stream object and then cast that image object to an itextsharp image one.
explore the overloads of iTextSharp.text.Image
EDIT:
Although the code is in C#, it might help you.
Get image from your local drive as:
Bitmap image1;
image1 = new Bitmap(#"C:\Documents and Settings\All Users\"
+ #"Documents\My Music\music.jpeg", true);
Note:: If you have the image on your application folder then we have functions to get the local file path of them in C#. Don't know about Java. Images from external site can be downloaded as
System.Net.WebClient client = new WebClient();
client.DownloadFile(imageURL, localPathname); // look into java to get local path
Now convert this byte stream to an image object as
MemoryStream imgMemoryStream = new MemoryStream(imgByteArray);
Image myImage = Drawing.Image.FromStream(imgMemoryStream);
Now acreate an iTextSharp image object from it and add it to your doucment as
iTextSharp.text.Image pic = iTextSharp.text.Image.GetInstance(myImage, System.Drawing.Imaging.ImageFormat.Jpeg);
document.Add(pic);
Hope this helps you.
I also faced to same issue..
but it was working with the image absolute path. it seems not working with remote path.
What id did here is save the image in temp location of file system and generates pdf , finally delete the image file from temp location.
<img src="/home/jboss/temp/imgs/img.png"/>
I was looking for same requirement and this is what worked for me:
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
htmlContext.setImageProvider(new AbstractImageProvider() {
public String getImageRootPath() {
return null;
}
#Override
public Image retrieve(String src) {
try {
Image img = com.itextpdf.text.Image.getInstance(new URL(src));
return Image.getInstance(img);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
});