我正在尝试使用apach-poi version 3.16将图像添加到excel。我可以用HSSFWorkbook
和XSSFWorkbook
来实现。但是当我试图为图像添加间距时,即如果我在XSSFClientAnchor
上设置dx1
,dy1
,dx2
,dy2
坐标,则不会生效。同样的事情也发生在HSSFClientAnchor
上。我附上这两个类和相应的Excel文件生成。请问你可以帮助我如何使用XSSFClientAnchor
实现相同的结果。
HSSF类
package poisamples;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFPicture;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class HSSFImage {
public static void main(String[] args) throws IOException {
String imageFile = "test.png";
String outputFile = "image-sutpid.xls";
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("Image");
HSSFClientAnchor anchor = new HSSFClientAnchor(100,100,100,100,(short)0, (short)0, (short)0, (short)3);
sheet.setColumnWidth(0, 6000);
anchor.setAnchorType(AnchorType.DONT_MOVE_AND_RESIZE);
int index = sheet.getWorkbook().addPicture(imageToBytes(imageFile), HSSFWorkbook.PICTURE_TYPE_PNG);
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
HSSFPicture picture = patriarch.createPicture(anchor, index);
picture.resize();
FileOutputStream fos = new FileOutputStream(outputFile);
workbook.write(fos);
}
private static byte[] imageToBytes(String imageFilename) throws IOException {
File imageFile;
FileInputStream fis = null;
ByteArrayOutputStream bos;
int read;
try {
imageFile = new File(imageFilename);
fis = new FileInputStream(imageFile);
bos = new ByteArrayOutputStream();
while ((read = fis.read()) != -1) {
bos.write(read);
}
return (bos.toByteArray());
} finally {
if (fis != null) {
try {
fis.close();
fis = null;
} catch (IOException ioEx) {
// Nothing to do here
}
}
}
}
}
XSSF类
package poisamples;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFPicture;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType;
public class XSSFImage {
public static void main(String[] args) throws IOException {
String imageFile = "test.png";
String outputFile = "image-sutpid.xlsx";
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("Image");
XSSFClientAnchor anchor = new XSSFClientAnchor(100,100,100,100,0, 0, 0, 3);
sheet.setColumnWidth(0, 6000);
anchor.setAnchorType(AnchorType.DONT_MOVE_AND_RESIZE);
int index = sheet.getWorkbook().addPicture(imageToBytes(imageFile), XSSFWorkbook.PICTURE_TYPE_PNG);
XSSFDrawing patriarch = sheet.createDrawingPatriarch();
XSSFPicture picture = patriarch.createPicture(anchor, index);
picture.resize();
FileOutputStream fos = new FileOutputStream(outputFile);
workbook.write(fos);
}
private static byte[] imageToBytes(String imageFilename) throws IOException {
File imageFile;
FileInputStream fis = null;
ByteArrayOutputStream bos;
int read;
try {
imageFile = new File(imageFilename);
fis = new FileInputStream(imageFile);
bos = new ByteArrayOutputStream();
while ((read = fis.read()) != -1) {
bos.write(read);
}
return (bos.toByteArray());
} finally {
if (fis != null) {
try {
fis.close();
fis = null;
} catch (IOException ioEx) {
// Nothing to do here
}
}
}
}
}
HSSF结果:
XSSF结果:
使用的图像:
1条答案
按热度按时间e7arh2l61#
问题是微软使用的不同的奇怪测量单位,以及二进制文件系统
*.xls
和Office Open XML*.xlsx
不仅在文件存储方面而且在一般方法上都有很大不同。如ClientAnchor所述:“注意- XSSF和HSSF的坐标系略有不同,XSSF中的值要大Units.EMU_PER_PIXEL”。但这并不是全部真相。
dx
和dy
的含义完全不同。在二进制文件系统*.xls
中,这些值取决于column-width
/default column-width
和row-height
/default row-height
的因子。不要问我在我的例子中使用的因子14.75
。这只是Trial&Error。关于你的代码,要提到的是,如果你想将图片缩放到它的原始大小,那么只需要一个单元格锚。这将锚定图片的左上边缘。如果锚将确定图片的大小,则仅需要两个单元锚。然后,锚中的第一个单元格锚定图片的左上边缘,而锚中的第二个单元格锚定图片的右下边缘。
下面的示例使用
1/256th of a character width
作为dx
的度量单位,因为列宽也在此度量单位中。它使用point
作为dy
的测量单位,因为行高也在这个测量单位中。至少找到了
*-xls
二进制文件格式的dx
和dy
的定义。它在2.5.193 OfficeArtClientAnchorSheet中定义。dx
:值表示为单元格宽度的1024次方。dy
:该值表示为该单元格高度的256次方。有了这个,代码应该是这样的:
但是,最好将所有长度都以像素为测量单位,以避免从pt和/或字符宽度的256分之一转换为像素。例如Why the same image export excel using HSSFWorkbook can use SXSSFWorkbook can not。