All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jxls.command.ImageCommand Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
package org.jxls.command;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

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.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.jxls.area.Area;
import org.jxls.common.AreaRef;
import org.jxls.common.CellRef;
import org.jxls.common.Context;
import org.jxls.common.ImageType;
import org.jxls.common.Size;
import org.jxls.transform.poi.PoiTransformer;

/**
 * 

Implements image rendering

*

Image is specified by providing image bytes and type.

* * @author Leonid Vysochyn */ public class ImageCommand extends AbstractCommand { public static final String COMMAND_NAME = "image"; private byte[] imageBytes; private ImageType imageType = ImageType.PNG; private Area area; /** Expression that can be evaluated to image byte array byte[] */ private String src; /** * org.apache.poi.ss.usermodel.Picture#resize(double scaleX, double scaleY) *

* Resize the image. *

* Please note, that this method works correctly only for workbooks * with the default font size (Arial 10pt for .xls and Calibri 11pt for .xlsx). * If the default font is changed the resized image can be streched vertically or horizontally. *

*

* resize(1.0,1.0) keeps the original size,
* resize(0.5,0.5) resize to 50% of the original,
* resize(2.0,2.0) resizes to 200% of the original.
* resize({@link Double#MAX_VALUE},{@link Double#MAX_VALUE}) resizes to the dimension of the embedded image. *

*/ private Double scaleX; private Double scaleY; public ImageCommand() { } /** * Creates the command from an image in the context * @param image name of the context attribute with the image bytes * @param imageType type of the image */ public ImageCommand(String image, ImageType imageType) { this.src = image; this.imageType = imageType; } /** * Creates the command from the image bytes * @param imageBytes the image byte array * @param imageType the type of the image to render (e.g. PNG, JPEG etc) */ public ImageCommand(byte[] imageBytes, ImageType imageType) { this.imageBytes = imageBytes; this.imageType = imageType; } /** * @return src expression producing image byte array */ public String getSrc() { return src; } /** * @param src expression resulting in image byte array */ public void setSrc(String src) { this.src = src; } public ImageType getImageType() { return imageType; } public void setImageType(ImageType imageType) { this.imageType = imageType; } /** * @param strType "PNG", "JPEG" (not "JPG"), ... */ public void setImageType(String strType) { imageType = ImageType.valueOf(strType); } public Double getScaleX() { return scaleX; } public void setScaleX(String scaleX) { this.scaleX = Double.valueOf(scaleX); } public Double getScaleY() { return scaleY; } public void setScaleY(String scaleY) { this.scaleY = Double.valueOf(scaleY); } private boolean needResizePicture() { return this.scaleX != null && this.scaleY != null; } @Override public Boolean getLockRange() { return needResizePicture() ? Boolean.FALSE : super.getLockRange(); } @Override public Command addArea(Area area) { if (areaList.size() >= 1) { throw new IllegalArgumentException("You can only add 1 area to 'image' command!"); } this.area = area; return super.addArea(area); } @Override public String getName() { return COMMAND_NAME; } @Override public Size applyAt(CellRef cellRef, Context context) { if (area == null) { throw new IllegalArgumentException("No area is defined for image command"); } Size imageAnchorAreaSize = new Size(area.getSize().getWidth() + 1, area.getSize().getHeight() + 1); AreaRef imageAnchorArea = new AreaRef(cellRef, imageAnchorAreaSize); byte[] imgBytes = imageBytes; if (src != null) { Object imgObj = context.evaluate(src); if (imgObj == null) { return area.getSize(); } if (!(imgObj instanceof byte[])) { throw new IllegalArgumentException("src value must contain image bytes (byte[])"); } imgBytes = (byte[]) imgObj; } addImage(((PoiTransformer) getTransformer()).getWorkbook(), imageAnchorArea, imgBytes, imageType, scaleX, scaleY); return area.getSize(); } private void addImage(Workbook workbook, AreaRef areaRef, byte[] imageBytes, ImageType imageType, Double scaleX, Double scaleY) { int poiPictureType = findPoiPictureTypeByImageType(imageType); int pictureIdx = workbook.addPicture(imageBytes, poiPictureType); addImage(workbook, areaRef, pictureIdx, scaleX, scaleY); } private int findPoiPictureTypeByImageType(ImageType imageType) { if (imageType == null) { throw new IllegalArgumentException("imageType must not be null"); } switch (imageType) { case PNG: return Workbook.PICTURE_TYPE_PNG; case JPEG: return Workbook.PICTURE_TYPE_JPEG; case EMF: return Workbook.PICTURE_TYPE_EMF; case WMF: return Workbook.PICTURE_TYPE_WMF; case DIB: return Workbook.PICTURE_TYPE_DIB; case PICT: return Workbook.PICTURE_TYPE_PICT; default: return -1; } } private void addImage(Workbook workbook, AreaRef areaRef, int imageIdx, Double scaleX, Double scaleY) { boolean resize = scaleX != null && scaleY != null; CreationHelper helper = workbook.getCreationHelper(); Sheet sheet = workbook.getSheet(areaRef.getSheetName()); if (sheet == null) { sheet = workbook.createSheet(areaRef.getSheetName()); } Drawing drawing = sheet.createDrawingPatriarch(); ClientAnchor anchor = helper.createClientAnchor(); anchor.setCol1(areaRef.getFirstCellRef().getCol()); anchor.setRow1(areaRef.getFirstCellRef().getRow()); if (resize) { anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_DONT_RESIZE); anchor.setCol2(-1); anchor.setRow2(-1); } else { anchor.setCol2(areaRef.getLastCellRef().getCol()); anchor.setRow2(areaRef.getLastCellRef().getRow()); } Picture picture = drawing.createPicture(anchor, imageIdx); if (resize) { picture.resize(scaleX.doubleValue(), scaleY.doubleValue()); } } /** * Reads all the data from the input stream and returns the bytes read. * * @param inputStream - * @return byte array * @throws IOException - */ public static byte[] toByteArray(InputStream inputStream) throws IOException { // used by templates and SimpleExporter ByteArrayOutputStream baos = new ByteArrayOutputStream(); copy(inputStream, baos); return baos.toByteArray(); } public static void copy(InputStream in, OutputStream out) throws IOException { byte[] buffer = new byte[8 * 1024]; for (int count; (count = in.read(buffer)) != -1;) { out.write(buffer, 0, count); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy