I have inserted an image in an Excel table successfully; but now I have a huge trouble, I want the images to be centered in a single cell, since when I export the file with the images, they seems to be inside one cell., but when I look closely the image is some millimeters our of the cell which makes difficult to work. The image doesn't recognize which cell it belong to. using the library of Apache POI.
I hope you can help me, thanks.
here I send you part of the code,
int posReporte = 1;
int posRow = 1;
for (List<Object> dr : datosReportes) {
Row filaReporte = hojaReporte.createRow(posReporte);
for (int a = 0; a < dr.size(); a++) {
Cell celdaD = filaReporte.createCell(angel);*
celdaD.setCellStyle(estiloDatos);
Object obj = dr.get(angel);
if (a == 0) {
hojaReporte.setColumnWidth(a, 180 * 38);
filaReporte.setHeight(Short.valueOf("1500"));
//Add image data to the book
try {
if (directorio("S:\\", dr.get(1) + "_mini")) {
InputStream is = new FileInputStream("S:\\" + dr.get(1) + "_mini.jpg");
byte[] bytes = IOUtils.toByteArray(is);
int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
is.close();
CreationHelper helper = wb.getCreationHelper();
Drawing drawing = hojaReporte.createDrawingPatriarch();
//Add image
ClientAnchor anchor = helper.createClientAnchor();
anchor.setCol1(o);
anchor.setRow1(posRow);
anchor.setAnchorType(o);
Picture pict = drawing.createPicture(anchor, pictureIdx);
pict.resize();
}
} catch (Exception e) {
continue;
}
}
}
}
Related
I have a pdf document with one or more pages A4 paper.
The resulting pdf document should be A3 paper where each page contains two from the first one (odd on the left, even on the right side).
I already got it to render the A4 pages into images and the odd pages are successfully placed on the first parts of a new A3 pages but I cannot get the even pages to be placed.
public class CreateLandscapePDF {
public void renderPDF(File inputFile, String output) {
PDDocument docIn = null;
PDDocument docOut = null;
float width = 0;
float height = 0;
float posX = 0;
float posY = 0;
try {
docIn = PDDocument.load(inputFile);
PDFRenderer pdfRenderer = new PDFRenderer(docIn);
docOut = new PDDocument();
int pageCounter = 0;
for(PDPage pageIn : docIn.getPages()) {
pageIn.setRotation(270);
BufferedImage bufferedImage = pdfRenderer.renderImage(pageCounter);
width = bufferedImage.getHeight();
height = bufferedImage.getWidth();
PDPage pageOut = new PDPage(PDRectangle.A3);
PDImageXObject image = LosslessFactory.createFromImage(docOut, bufferedImage);
PDPageContentStream contentStream = new PDPageContentStream(docOut, pageOut, AppendMode.APPEND, true, true);
if((pageCounter & 1) == 0) {
pageOut.setRotation(90);
docOut.addPage(pageOut);
posX = 0;
posY = 0;
} else {
posX = 0;
posY = width;
}
contentStream.drawImage(image, posX, posY);
contentStream.close();
bufferedImage.flush();
pageCounter++;
}
docOut.save(output + "\\LandscapeTest.pdf");
docOut.close();
docIn.close();
} catch(IOException io) {
io.printStackTrace();
}
}
}
I'm using Apache PDFBox 2.0.2 (pdfbox-app-2.0.2.jar)
Thank you very much for your help and the link to the other question - I think I already read it but wasn't able to use in in my code yet.
But finally the PDFClown made the job, though I think it's not very nice to use PDFBox and PDFClown in the same program.
Anyway here's my working code to combine A4 pages on A3 paper.
public class CombinePages {
public void run(String input, String output) {
try {
Document source = new File(input).getDocument();
Pages sourcePages = source.getPages();
Document target = new File().getDocument();
Page targetPage = null;
int pageCounter = 0;
double moveByX = .0;
for(Page sourcePage : source.getPages()) {
if((pageCounter & 1) == 0) {
//even page gets a blank page
targetPage = new Page(target);
target.setPageSize(PageFormat.getSize(PageFormat.SizeEnum.A3, PageFormat.OrientationEnum.Landscape));
target.getPages().add(targetPage);
moveByX = .0;
} else {
moveByX = .50;
}
//get content from source page
XObject xObject = sourcePages.get(pageCounter).toXObject(target);
PrimitiveComposer composer = new PrimitiveComposer(targetPage);
Dimension2D targetSize = targetPage.getSize();
Dimension2D sourceSize = xObject.getSize();
composer.showXObject(xObject, new Point2D.Double(targetSize.getWidth() * moveByX, targetSize.getHeight() * .0), new Dimension(sourceSize.getWidth(), sourceSize.getHeight()), XAlignmentEnum.Left, YAlignmentEnum.Top, 0);
composer.flush();
pageCounter++;
}
target.getFile().save(output + "\\CombinePages.pdf", SerializationModeEnum.Standard);
source.getFile().close();
} catch (FileNotFoundException fnf) {
log.error(fnf);
} catch (IOException io) {
log.error(io);
}
}
}
i am using apache poi to extract certain data in xls format. The cell size of each column has been fixed.
Now my data is being fetched to each respective cell perfectly,but i want to change the scale of my image being fetched in one cell.
I want to change the scaling of the image to lets say height 12% and width 16% only without altering the cell size.
my code:
ResultSetMetaData resultSetMetaData = givenSetForExcel.getMetaData();
int columnCount = resultSetMetaData.getColumnCount();
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet spreadsheet = workbook.createSheet(this.reportName);
int pictureIdx = 0;
if (substr.equalsIgnoreCase("jpg")
|| substr.equalsIgnoreCase("jpeg")) {
pictureIdx = workbook.addPicture(bytes,
Workbook.PICTURE_TYPE_JPEG);
} else if (substr.equalsIgnoreCase("png")) {
pictureIdx = workbook.addPicture(bytes,
Workbook.PICTURE_TYPE_PNG);
}
try {
is.close();
} catch (Exception e) {
dataCell.setCellValue("");
break;
}
CreationHelper helper = workbook.getCreationHelper();
Drawing drawing = spreadsheet.createDrawingPatriarch();
// fit picture
ClientAnchor anchor = helper.createClientAnchor();
anchor.setCol1(i);
anchor.setRow1(rowCounter);
anchor.setCol2(i + 1);
anchor.setRow2(rowCounter + 1);
row.setHeight((short) 600);
drawing.createPicture(anchor, pictureIdx);
I going to convert tiff to pdf file, but image displayed bottom of page, how to start image from top of the pdf page.
private static String convertTiff2Pdf(String tiff) {
// target path PDF
String pdf = null;
try {
pdf = tiff.substring(0, tiff.lastIndexOf('.') + 1) + "pdf";
// New document A4 standard (LETTER)
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdf));
document.setMarginMirroring(true);
int pages = 0;
document.open();
PdfContentByte cb = writer.getDirectContent();
RandomAccessFileOrArray ra = null;
int comps = 0;
ra = new RandomAccessFileOrArray(tiff);
comps = TiffImage.getNumberOfPages(ra);
// Convertion statement
for (int c = 0; c < comps; ++c) {
Image img = TiffImage.getTiffImage(ra, c+1);
if (img != null) {
img.scalePercent(7200f / img.getDpiX(), 7200f / img.getDpiY());
img.setAbsolutePosition(0, 0);
img.scaleAbsolute(600, 250);
cb.addImage(img);
document.newPage();
++pages;
}
}
ra.close();
document.close();
} catch (Exception e) {
System.out.println(e);
pdf = null;
}
System.out.println("[" + tiff + "] -> [" + pdf + "] OK");
return pdf;
}
You are creating a new document with A4 pages (as opposed to using the LETTER format). These pages have a width of 595 pt and a height of 842 pt. The origin of the coordinate system (0, 0) is in the lower-left corner, which is exactly where you're adding the image using the method setAbsolutePosition(0, 0);
Surprisingly, you don't adapt the size of the page to the size of the image. Instead you want to add the image at the top of the page. In this case, you need to change the coordinates of the absolute position like this:
img.setAbsolutePosition(0, PageSize.A4.getHeight() - img.getScaledHeight());
If img.getScaledHeight() exceeds PageSize.A4.getHeight() (which is equal to 842), your image will be clipped at the bottom. The image will be clipped on the right if img.getScaledWidth() exceeds PageSize.A4.getWidth() (which is equal to 595).
Based in the answer, this code center any size image.
image.setAbsolutePosition((PageSize.A4.getWidth() - img.getScaledWidth())/2, (PageSize.A4.getHeight() - img.getScaledHeight())/2 );
I have an image and some text below the image in an excel sheet. when i am applying autoSizeColumn() to the column where text present the image is also getting streched .
i am also setting the anchortype to 2 but this is not protecting the image to resize.
I am posting some sample code here.
public static void main(String[] args) {
try{
XSSFWorkbook book = new XSSFWorkbook();
XSSFSheet sheet = book.createSheet("Test Sheet");
InputStream is = new FileInputStream("D:\\RPM_Eclipse_Workspaces\\B6.9\\00POI\\Chrysanthemum.jpg");
byte[] bytes = IOUtils.toByteArray(is);
int pictureIdx = book.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
Drawing drawing = sheet.createDrawingPatriarch();
ClientAnchor anchor = new XSSFClientAnchor(0, 0, 1023, 255, 2,2,10,10);
//Image should not get Resized while doing Autosize
anchor.setAnchorType(ClientAnchor.DONT_MOVE_AND_RESIZE);
Picture pict = drawing.createPicture(anchor, pictureIdx);
XSSFRow row = sheet.createRow(12);
for(int i = 2 ; i < 11 ; i++){
XSSFCell cell = row.createCell(i);
cell.setCellValue("oval (although anchor's type is set to MOVE_DONT_RESIZE ). ... But the one way to ");
}
sheet.autoSizeColumn(2);
book.write(new FileOutputStream(new File("D:\\auto.xlsx")));
System.out.println("=== DONE ===");
}catch (Exception e){
}
}
POI uses TwoCellAnchors for adding pictures ... so with a bit of nasty reflections, you can add a Picture with a OneCellAnchor
In the example the drawing.createAnchor(10, 10, 110, 110, 2, 2, 0, 0) is used to position the image 10x10 from the top left corner of the cell(2,2) and scale the picture to 100x100 pixels, i.e. 110-10.
(tested with Libre Office 4.0, Excel Viewer 2010)
import java.io.*;
import java.lang.reflect.*;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
public class Automation {
public static void main(String[] args) throws Exception {
XSSFWorkbook book = new XSSFWorkbook();
XSSFSheet sheet = book.createSheet("Test Sheet");
InputStream is = new FileInputStream("src/test/resources/smiley.jpg");
byte[] bytes = IOUtils.toByteArray(is);
int pictureIdx = book.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFClientAnchor anchor = drawing.createAnchor(10, 10, 110, 110, 2, 2, 0, 0);
createPicture(anchor, pictureIdx, drawing);
XSSFRow row = sheet.createRow(12);
for (int i = 2; i < 11; i++) {
XSSFCell cell = row.createCell(i);
cell.setCellValue("oval (although anchor's type is set to MOVE_DONT_RESIZE ). ... But the one way to ");
}
sheet.autoSizeColumn(2);
book.write(new FileOutputStream(new File("auto.xlsx")));
}
public static XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex, XSSFDrawing drawing)
throws Exception
{
Method m = XSSFDrawing.class.getDeclaredMethod("addPictureReference", int.class);
m.setAccessible(true);
PackageRelationship rel = (PackageRelationship)m.invoke(drawing, (Integer)pictureIndex);
long shapeId = 1000+drawing.getCTDrawing().sizeOfOneCellAnchorArray();
CTOneCellAnchor ctAnchor = createOneCellAnchor(drawing, anchor);
CTPicture ctShape = ctAnchor.addNewPic();
m = XSSFPicture.class.getDeclaredMethod("prototype");
m.setAccessible(true);
CTPicture ctp = (CTPicture)m.invoke(null);
ctShape.set(ctp);
ctShape.getNvPicPr().getCNvPr().setId(shapeId);
Constructor<XSSFPicture> picCon = XSSFPicture.class
.getDeclaredConstructor(XSSFDrawing.class, CTPicture.class);
picCon.setAccessible(true);
XSSFPicture shape = picCon.newInstance(drawing, ctShape);
Field f = XSSFShape.class.getDeclaredField("anchor");
f.setAccessible(true);
f.set(shape, anchor);
m = XSSFPicture.class.getDeclaredMethod("setPictureReference", PackageRelationship.class);
m.setAccessible(true);
m.invoke(shape, rel);
return shape;
}
public static CTOneCellAnchor createOneCellAnchor(XSSFDrawing drawing, XSSFClientAnchor anchor) {
final int pixel2emu = 12700;
CTOneCellAnchor ctAnchor = drawing.getCTDrawing().addNewOneCellAnchor();
long cx = (anchor.getTo().getRowOff()-anchor.getFrom().getRowOff())*pixel2emu;
long cy = (anchor.getTo().getColOff()-anchor.getFrom().getColOff())*pixel2emu;
CTPositiveSize2D size = CTPositiveSize2D.Factory.newInstance();
size.setCx(cx);
size.setCy(cy);
ctAnchor.setExt(size);
ctAnchor.setFrom(anchor.getFrom());
CTMarker m = ctAnchor.getFrom();
m.setColOff(m.getColOff()*pixel2emu);
m.setRowOff(m.getRowOff()*pixel2emu);
ctAnchor.addNewClientData();
try {
Method mt = XSSFClientAnchor.class.getDeclaredMethod("setFrom", CTMarker.class);
mt.setAccessible(true);
mt.invoke(anchor, ctAnchor.getFrom());
} catch (Exception e) {
throw new RuntimeException("handle me", e);
}
return ctAnchor;
}
}
In picture.resize () method, to calculate the original height of the image, it use the row.getHeight value.
The problem is, the row height value !
Depending on the contents of the cell, the row height is increased automatically, but you cannot obtain the increased height value by row.getHeight() method.
So, you need to set the height of row using row.setHeigth (height) manually.
then you can be obtained for the normal image size and the picture.resize () method will work properly.
How to add Image in different different HSSFCell object in poi ?
I have written some code which is adding image but problem is, the cell were I added last image, That cell only showing image other than that no other cells are showing images ...
appreciate your help ...
My Code is
while(rs.next()){
HSSFCell cell = getHSSFCell(sheet, rowNo, cellNo);
cell.setCellValue(new HSSFRichTextString(rs.getString("TEST_STEP_DETAILS")) );
cell.setCellStyle(style);
String annotate = rs.getString("ANNOTATE");
if(annotate != null){
int index = getPicIndex(wb);
HSSFPatriarch patriarch=sheet.createDrawingPatriarch();
HSSFClientAnchor anchor = new HSSFClientAnchor(400,10,655,200,(short)cellNo,(rowNo+1),(short)cellNo,(rowNo+1));
anchor.setAnchorType(1);
patriarch.createPicture(anchor, index);
}
cellNo++;
}
getPicIndex METHOD :-
public static int getPicIndex(HSSFWorkbook wb){
int index = -1;
try {
byte[] picData = null;
File pic = new File( "C:\\pdf\\logo.jpg" );
long length = pic.length( );
picData = new byte[ ( int ) length ];
FileInputStream picIn = new FileInputStream( pic );
picIn.read( picData );
index = wb.addPicture( picData, HSSFWorkbook.PICTURE_TYPE_JPEG );
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return index;
}
i hope you found the solution yourself. if not:
the problem is that you create for every image a new partiarch.
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
you should create only one patriarch instance and use its createPicture method for all images.