如何使用 POI 将 excel 中的一张图片替换为另一张图片
how to replace an image with another image in excel using POI
我需要帮助使用 Apache POI 将 excel sheet 中的一张图片替换为另一张图片。
int myPictureId=0;
List<XSSFShape> pictures = drawing.getShapes();
for(XSSFShape shape : pictures) {
XSSFPicture picture = (XSSFPicture)shape; //Get picture
byte[] data = picture.getPictureData().getData(); //Get picture data
XSSFClientAnchor anchor = picture.getClientAnchor(); //Get anchor
ByteArrayInputStream byteInput = new ByteArrayInputStream(data);
BufferedImage image = ImageIO.read(byteInput);
data = getByteArrayFromImage(image, 400, data, picture.getPictureData().suggestFileExtension());
myPictureId = workbook.addPicture(new ByteArrayInputStream(data), Workbook.PICTURE_TYPE_PNG);
picture = drawing.createPicture(anchor, myPictureId);
}
我正在使用 getByteArrayFromImage 方法来压缩我的图像并将原始图像替换为压缩后的图像。我还尝试使用 XSSFClientAnchor 将压缩图像附加到原始图像,但 excel 将原始图像与压缩图像重叠。
不清楚getByteArrayFromImage
在做什么。但它似乎只改变了源 BufferedImage
的数据字节上的某些内容,源 BufferedImage
从源 XSSFPictureData
的数据字节和 returns 然后更改了数据字节。
如果这个新的数据字节应该替换源XSSFPictureData
中的源数据字节,那么下面的方法可以做到这一点:
void replacePictureData(XSSFPictureData source, byte[] data) {
try ( ByteArrayInputStream in = new ByteArrayInputStream(data);
OutputStream out = source.getPackagePart().getOutputStream();
) {
byte[] buffer = new byte[2048];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
XSSFPictureData
是 *.xlsx
ZIP 压缩包的一部分,因此它提供了 getOutputStream
方法。
下面完整的例子展示了它的整体。我的 getByteArrayFromImage
将文本“CHANGED”写入 Excel 文件中的图片。
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.*;
import java.io.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.List;
class ExcelReplacePictures {
static void replacePictureData(XSSFPictureData source, byte[] data) {
try ( ByteArrayInputStream in = new ByteArrayInputStream(data);
OutputStream out = source.getPackagePart().getOutputStream();
) {
byte[] buffer = new byte[2048];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
static byte[] getByteArrayFromImage(BufferedImage image, Dimension dimension, byte[] data, String type) {
try {
Graphics g = image.getGraphics();
g.setColor(Color.red);
g.setFont(new Font("Serif", Font.BOLD, 40));
String s = "CHANGED";
FontMetrics fm = g.getFontMetrics();
int x = image.getWidth() / 2 - fm.stringWidth(s) / 2;
int y = image.getHeight() / 2 + fm.getHeight() / 2;
g.drawString(s, x, y);
g.dispose();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, type, baos);
data = baos.toByteArray();
} catch (Exception ex) {
ex.printStackTrace();
}
return data;
}
public static void main(String[] args) throws Exception {
try (XSSFWorkbook workbook = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream("./ExcelWithPictures.xlsx"));
FileOutputStream out = new FileOutputStream("./ExcelWithPicturesNew.xlsx");
) {
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
XSSFSheet sheet = workbook.getSheetAt(i);
XSSFDrawing drawing = sheet.getDrawingPatriarch();
List<XSSFShape> shapes = drawing.getShapes();
for (XSSFShape shape : shapes) {
if (shape instanceof XSSFPicture) {
XSSFPicture picture = (XSSFPicture)shape;
XSSFPictureData pictureData = picture.getPictureData();
byte[] data = pictureData.getData();
ByteArrayInputStream byteInput = new ByteArrayInputStream(data);
BufferedImage image = ImageIO.read(byteInput);
data = getByteArrayFromImage(image, picture.getImageDimension(), data, pictureData.suggestFileExtension());
replacePictureData(pictureData, data);
}
}
}
workbook.write(out);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
我需要帮助使用 Apache POI 将 excel sheet 中的一张图片替换为另一张图片。
int myPictureId=0;
List<XSSFShape> pictures = drawing.getShapes();
for(XSSFShape shape : pictures) {
XSSFPicture picture = (XSSFPicture)shape; //Get picture
byte[] data = picture.getPictureData().getData(); //Get picture data
XSSFClientAnchor anchor = picture.getClientAnchor(); //Get anchor
ByteArrayInputStream byteInput = new ByteArrayInputStream(data);
BufferedImage image = ImageIO.read(byteInput);
data = getByteArrayFromImage(image, 400, data, picture.getPictureData().suggestFileExtension());
myPictureId = workbook.addPicture(new ByteArrayInputStream(data), Workbook.PICTURE_TYPE_PNG);
picture = drawing.createPicture(anchor, myPictureId);
}
我正在使用 getByteArrayFromImage 方法来压缩我的图像并将原始图像替换为压缩后的图像。我还尝试使用 XSSFClientAnchor 将压缩图像附加到原始图像,但 excel 将原始图像与压缩图像重叠。
不清楚getByteArrayFromImage
在做什么。但它似乎只改变了源 BufferedImage
的数据字节上的某些内容,源 BufferedImage
从源 XSSFPictureData
的数据字节和 returns 然后更改了数据字节。
如果这个新的数据字节应该替换源XSSFPictureData
中的源数据字节,那么下面的方法可以做到这一点:
void replacePictureData(XSSFPictureData source, byte[] data) {
try ( ByteArrayInputStream in = new ByteArrayInputStream(data);
OutputStream out = source.getPackagePart().getOutputStream();
) {
byte[] buffer = new byte[2048];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
XSSFPictureData
是 *.xlsx
ZIP 压缩包的一部分,因此它提供了 getOutputStream
方法。
下面完整的例子展示了它的整体。我的 getByteArrayFromImage
将文本“CHANGED”写入 Excel 文件中的图片。
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.*;
import java.io.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.List;
class ExcelReplacePictures {
static void replacePictureData(XSSFPictureData source, byte[] data) {
try ( ByteArrayInputStream in = new ByteArrayInputStream(data);
OutputStream out = source.getPackagePart().getOutputStream();
) {
byte[] buffer = new byte[2048];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
static byte[] getByteArrayFromImage(BufferedImage image, Dimension dimension, byte[] data, String type) {
try {
Graphics g = image.getGraphics();
g.setColor(Color.red);
g.setFont(new Font("Serif", Font.BOLD, 40));
String s = "CHANGED";
FontMetrics fm = g.getFontMetrics();
int x = image.getWidth() / 2 - fm.stringWidth(s) / 2;
int y = image.getHeight() / 2 + fm.getHeight() / 2;
g.drawString(s, x, y);
g.dispose();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, type, baos);
data = baos.toByteArray();
} catch (Exception ex) {
ex.printStackTrace();
}
return data;
}
public static void main(String[] args) throws Exception {
try (XSSFWorkbook workbook = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream("./ExcelWithPictures.xlsx"));
FileOutputStream out = new FileOutputStream("./ExcelWithPicturesNew.xlsx");
) {
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
XSSFSheet sheet = workbook.getSheetAt(i);
XSSFDrawing drawing = sheet.getDrawingPatriarch();
List<XSSFShape> shapes = drawing.getShapes();
for (XSSFShape shape : shapes) {
if (shape instanceof XSSFPicture) {
XSSFPicture picture = (XSSFPicture)shape;
XSSFPictureData pictureData = picture.getPictureData();
byte[] data = pictureData.getData();
ByteArrayInputStream byteInput = new ByteArrayInputStream(data);
BufferedImage image = ImageIO.read(byteInput);
data = getByteArrayFromImage(image, picture.getImageDimension(), data, pictureData.suggestFileExtension());
replacePictureData(pictureData, data);
}
}
}
workbook.write(out);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}