I'm working on piece of code that generates Excel (*.xlsx) workbook with 2 sheets. On both I'm going to place in the top left corner the same logo.png picture (151x90px). First sheet differs only from the second in first column width. It's wider on first sheet.
After excel file generation the picture on the first sheet looks fine however on the second sheet it's wider (110%)
How can I make pictures have it's original size on both sheets?
I'm using apache-poi 3.17
Here is my example code:
package mchodun.excel;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Paths;
public class ExcelFileTest {
#Test
public void testImage() throws IOException {
Workbook workbook = new SXSSFWorkbook(100);
InputStream is = new FileInputStream(
"/Users/mchodun/Desktop/logo.png");
byte[] pictureBytes = IOUtils.toByteArray(is);
createSheet(workbook, pictureBytes, true);
createSheet(workbook, pictureBytes, false);
final File fileDest = Paths.get("/Users/mchodun/Desktop", "test.xlsx")
.toFile();
// gets output stream
final OutputStream out = new FileOutputStream(fileDest);
workbook.write(out);
out.flush();
out.close();
}
private void createSheet(Workbook workbook, byte[] pictureBytes,
boolean changeColumnWidth) {
final int pictureIdx = workbook.addPicture(pictureBytes,
Workbook.PICTURE_TYPE_PNG);
Sheet sheet = workbook.createSheet();
if (changeColumnWidth) {
sheet.setColumnWidth(0, 16000);
}
final CreationHelper helper = workbook.getCreationHelper();
final Drawing drawing = sheet.createDrawingPatriarch();
final ClientAnchor anchor = helper.createClientAnchor();
// create an anchor with upper left cell and bottom right cell
anchor.setCol1(0);
anchor.setRow1(0);
anchor.setCol2(0);
anchor.setRow2(0);
Picture picture = drawing.createPicture(anchor, pictureIdx);
Row row0 = sheet.createRow(0);
row0.setHeight((short) (picture.getImageDimension().getHeight() * 15));
Row row1 = sheet.createRow(1);
Cell cell10 = row1.createCell(0);
cell10.setCellValue("Value");
picture.resize();
}
}
Related
I'm just beginner in java
I trying to convert PPT file to PDF file using apache poi and Itext library but i'm getting error of NoSuchMethodError
I tried all the version of Apache poi and poi-ooxml but i'm getting same error
please help me to findout Solution for this error
Here is my code :
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.usermodel.SlideShow;
import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
public class PPTtoPDF {
public PPTtoPDF() {
}
#SuppressWarnings("resource")
public void convertPPTToPDF(String sourcepath, String destinationPath) throws Exception {
FileInputStream inputStream = new FileInputStream(sourcepath);
double zoom = 2;
AffineTransform at = new AffineTransform();
at.setToScale(zoom, zoom);
Document pdfDocument = new Document();
PdfWriter pdfWriter = PdfWriter.getInstance(pdfDocument, new FileOutputStream(destinationPath));
PdfPTable table = new PdfPTable(1);
pdfWriter.open();
pdfDocument.open();
Dimension pgsize = null;
Image slideImage = null;
BufferedImage img = null;
SlideShow ppt = new SlideShow(inputStream);
pgsize = ppt.getPageSize();
Slide slide[] = ppt.getSlides();
System.out.println("Length----> "+slide.length);
pdfDocument.setPageSize(new Rectangle((float) pgsize.getWidth(), (float) pgsize.getHeight()));
pdfWriter.open();
pdfDocument.open();
for (int i = 0; i < slide.length; i++) {
img = new BufferedImage((int) Math.ceil(pgsize.width * zoom), (int) Math.ceil(pgsize.height * zoom), BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
graphics.setTransform(at);
graphics.setPaint(Color.white);
graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
slide[i].draw(graphics);
graphics.getPaint();
slideImage = Image.getInstance(img, null);
table.addCell(new PdfPCell(slideImage, true));
System.out.println(table);
}
pdfDocument.add(table);
pdfDocument.close();
pdfWriter.close();
System.out.println("Powerpoint file converted to PDF successfully");
}
public static void main(String[] args) throws Exception
{
PPTtoPDF pp = new PPTtoPDF();
pp.convertPPTToPDF("D:\\tp\\slides.ppt", "D:\\tp\\1.pdf");
}
}
and the error is
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.poi.POIDocument.<init>(Lorg/apache/poi/poifs/filesystem/DirectoryNode;Lorg/apache/poi/poifs/filesystem/POIFSFileSystem;)V
at org.apache.poi.hslf.HSLFSlideShow.<init>(HSLFSlideShow.java:134)
at org.apache.poi.hslf.HSLFSlideShow.<init>(HSLFSlideShow.java:120)
at org.apache.poi.hslf.HSLFSlideShow.<init>(HSLFSlideShow.java:107)
at org.apache.poi.hslf.usermodel.SlideShow.<init>(SlideShow.java:122)
at convertService.PPTtoPDF.convertPPTToPDF(PPTtoPDF.java:44)
at convertService.PPTtoPDF.main(PPTtoPDF.java:75)
See the Apache POI FAQ entry on this very topic. What has almost certainly happened is that you have added a new copy of POI to your classpath, but an older version was already there (from an earlier need, your framework etc), and Java is now getting confused about which one to use.
You could use tool for that:
mvn dependency
tree JDK 8: jdeps
(https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool)
jdeps is a new command-line tool added since JDK 8 for developers to
use to understand the static dependencies of their applications and
libraries. jdeps is a static analysis tool on the given class files
well,I modified my code to eliminate other factors:
package com.shangzhu.drt;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
/**
* Created by lixiaoming on 2017/6/26.
*/
public class ImageTest2 {
private static void insertImageWithPOI() throws Exception {
XSSFWorkbook wwb = new XSSFWorkbook();
XSSFSheet ws = wwb.createSheet("sheet0");
BufferedImage image = ImageIO.read(new File("D:/poi.png"));
ByteArrayOutputStream baps = new ByteArrayOutputStream();
ImageIO.write(image,"png",baps);
int pictureIdx = wwb.addPicture(baps.toByteArray(), Workbook.PICTURE_TYPE_PNG);
XSSFDrawing drawing = ws.createDrawingPatriarch();
XSSFCreationHelper helper = wwb.getCreationHelper();
XSSFClientAnchor anchor = helper.createClientAnchor();
anchor.setCol1(1);
anchor.setRow1(1);
Picture picture = drawing.createPicture(anchor, pictureIdx);
picture.resize();
File excelFile = new File("D:/POI.xlsx");
OutputStream ops = new FileOutputStream(excelFile);
wwb.write(ops);
}
public static void main(String[] args) {
try {
insertImageWithPOI();
} catch (Exception e) {
e.printStackTrace();
}
}
}
below is the picture("D:/poi.png") in the code:
D:/poi.png
I don't think the source code which is dealing image has problems,But I don't know what I missed
I confirm that there is a problem when default column size is used. XSSFPicture.resize needs calculating the column widths in pixels to get the XSSFClientAnchor Col2 and the Dx2. As long as default column size is used, then this calculation seems to be wrong.
A workaround could be defining explicit column sizes before using XSSFPicture.resize. Then the calculation of the column widths in pixels seems to be correct.
In your code:
...
Picture picture = drawing.createPicture(anchor, pictureIdx);
for (int c=0; c<20; c++) ws.setColumnWidth(c, 11*256);
picture.resize();
...
Just like the image, I want to make 1 and 3 align same with 2. The table is default alignment.
What should I do?
Here is a simple way of doing it , add both to the same paragraph
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
public class ItextMain {
public static final String DEST = "simple_table4.pdf";
public static void main(String[] args) throws IOException, DocumentException {
File file = new File(DEST);
// file.getParentFile().mkdirs();
new ItextMain().createPdf(DEST);
}
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
document.add(new Paragraph("1-Not aligned with table"));
document.add(new Chunk());
Paragraph p = new Paragraph();
p.setIndentationLeft(20);// (20);
PdfPTable table = new PdfPTable(4);
for (int aw = 0; aw < 16; aw++) {
table.addCell("hi");
}
table.setHorizontalAlignment(Element.ALIGN_LEFT);
p.add(table);
//document.add(table);
p.add("3- Aligned with table");
document.add(p);
document.close();
}
}
The iText 5 PdfPTable class has a width percentage attribute which holds the width percentage that the table will occupy in the page. By default this value is 80 and the resulting table is horizontally centered on the page, i.e. in particular it is indented.
To prevent this, simply set the percentage value to 100:
PdfPTable table = ...;
table.setWidthPercentage(100);
Alternatively set the horizontal alignment:
table.setHorizontalAlignment(Element.ALIGN_LEFT);
I am trying to convert the pptx to png images using apache-poi in java but it doesn't work with pptx generated by LibreOffice Impress (works fine with others ) and there is no exception thrown.
The resulting images I get are just the background with out the text content of the pptx.
Please see the links for the results.
The resulting image
Screen shot of Actual pptx slide
This is the basic code I got :
package com.preview;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
public class PptxToPng {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileInputStream is = new FileInputStream("~/Downloads/pptx/SamplePPTX.pptx");
XMLSlideShow ppt = new XMLSlideShow(is);
is.close();
double zoom = 2;
AffineTransform at = new AffineTransform();
at.setToScale(zoom, zoom);
Dimension pgsize = ppt.getPageSize();
List<XSLFSlide> slide = ppt.getSlides();
BufferedImage img = new BufferedImage((int)Math.ceil(pgsize.width*zoom),
(int)Math.ceil(pgsize.height*zoom), BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
graphics.setTransform(at);
graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
// Draw first page in the PPTX. First page starts at 0 position
slide.get(0).draw(graphics);
FileOutputStream out = new FileOutputStream("~/Downloads/pptx/converted.png");
javax.imageio.ImageIO.write(img, "png", out);
out.close();
ppt.close();
System.out.println("DONE");
}
}
poi-ooxml-3.15.jar comes with a tool called PPTX2PNG. It can be found in the package org.apache.poi.xslf.util
Execute it eg with parameters -scale 1 -format jpg pptx-file.pptx and it should write an image file to the same directory as the origin pptx file.
BTW: despite the name, it can write to png, jpg and gif formats.
I am trying to generate pdf file using itext. I need to add an element(Paragraph) above footer in the last page. I don't know how to position the element in that position.
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.ExceptionConverter;
import com.lowagie.text.Image;
import com.lowagie.text.Phrase;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfPageEventHelper;
import com.lowagie.text.pdf.PdfWriter;
public class PdfHeaderDecorator extends PdfPageEventHelper
{
public PdfHeaderDecorator()
{
super();
}
public void onEndPage(PdfWriter writer, Document document)
{
PdfPTable tableF = new PdfPTable(3);
try
{
tableF.setWidths(new int[]
{ 24, 24, 2 });
tableF.setTotalWidth(527);
tableF.setLockedWidth(true);
tableF.getDefaultCell().setFixedHeight(9);
tableF.getDefaultCell().setBorder(Rectangle.BOTTOM);
tableF.addCell(new Phrase("SOME Text"));
tableF.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
tableF.addCell(new Phrase(String.format("page %d ", writer.getPageNumber())));
PdfPCell cell = new PdfPCell(new Phrase("bla bla bla"));
cell.setBorder(Rectangle.BOTTOM);
tableF.addCell(cell);
tableF.writeSelectedRows(0, -1, 34, 30, writer.getDirectContent());
}
catch (DocumentException de)
{
throw new ExceptionConverter(de);
}
}
}
And add your header decorator to page event
pdfWriter.setPageEvent(new PdfHeaderDecorator());