FileInputStream in = new FileInputStream("testWorkbook.xlsx");
XSSFWorkbook wb = (XSSFWorkbook)WorkbookFactory.create(in);
InputStream inputStream = new FileInputStream("/home/test/test1.svg");
//Get the contents of an InputStream as a byte[].
byte[] imageData = IOUtils.toByteArray(inputStream);
// XSSFWorkbook.PICTURE_TYPE_SVG is not supported yet.
int pictureIndex = wb.addPicture(imageData, XSSFWorkbook.PICTURE_TYPE_SVG); // Preferred support
有什么方法可以将SVG
映像添加到XSSFWorkbook
中吗?
对SVG
的支持是Microsoft Office 365
的新功能。这就是为什么直到现在Apache poi
还不完全支持它(2021年5月,Apache poi 5.0.0
)。
要在Excel
中实现这种支持,需要知道Excel
如何插入SVG
图像。为了向后兼容,它将图像转换为png
。它将SVG
图像和PNG
图像都放入工作簿中。然后,它将png
图像显示为绘图中的形状。该形状具有对SVG
图像的附加引用,因此如果使用Excel 365
,也可以获得SVG
图像。
要在Apache POI
中实现这种支持,需要以下内容:
>
SVG
到PNG
的转换器。那里可以使用阿帕奇蜡染代码转换器。
扩展的XSSFWorkbook
,它提供单独的AddsVGPicture
方法,或者在AddPicture
方法中提供对SVG
的支持。但是扩展xssf...
类并不是那么简单,因为有些奇怪的决定将成员或方法设置为私有。
xssfrelation.image_svg
,在创建图片和形状时提供创建关系。但是XSSFRelation
完全不可扩展。因此,需要扩展低层POIXMLRelation
。
扩展的XSSFPictureData
,为新的POIXMLRelation
提供对所需图片构造函数的支持。
下面的代码提供了所有这些。在需要的地方对其进行评论。
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
class CreateExcelXSSFPictureSVG {
// use org.apache.batik.transcoder to convert SVG to PNG
static byte[] svgToPng(InputStream svg) throws Exception {
org.apache.batik.transcoder.image.PNGTranscoder t = new org.apache.batik.transcoder.image.PNGTranscoder();
org.apache.batik.transcoder.TranscoderInput input = new org.apache.batik.transcoder.TranscoderInput(svg);
java.io.ByteArrayOutputStream ostream = new java.io.ByteArrayOutputStream();
org.apache.batik.transcoder.TranscoderOutput output = new org.apache.batik.transcoder.TranscoderOutput(ostream);
t.transcode(input, output);
ostream.flush();
return ostream.toByteArray();
}
public static void main(String[] args) throws Exception {
String svgFilePath = "./Freesample.svg";
MyXSSFWorkbook workbook = new MyXSSFWorkbook(); // see MyXSSFWorkbook.java
// add SVG Image to workbook
FileInputStream is = new FileInputStream(svgFilePath);
int svgPictureIdx = workbook.addSVGPicture(is);
is.close();
// add PNG image to workbook
is = new FileInputStream(svgFilePath);
int pngPictureIdx = workbook.addPicture(svgToPng(is), Workbook.PICTURE_TYPE_PNG);
is.close();
// create sheet and get drawing
XSSFSheet sheet = workbook.createSheet("Sheet1");
XSSFDrawing drawing = sheet.createDrawingPatriarch();
// add SVG Image relation to drawing
XSSFPictureData pictureData = workbook.getAllPictures().get(svgPictureIdx);
org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart rp = drawing.addRelation(null, XSSFRelation.IMAGES, pictureData);
String svgRId = rp.getRelationship().getId();
// create anchor for picture shape
XSSFCreationHelper helper = workbook.getCreationHelper();
XSSFClientAnchor anchor = helper.createClientAnchor();
anchor.setCol1(1);
anchor.setRow1(1);
// create PNG picture shape
XSSFPicture pngPicture = drawing.createPicture(anchor, pngPictureIdx);
pngPicture.resize();
// set SVG extension to PNG picture shape
org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeArtExtension ext = pngPicture.getCTPicture().getBlipFill().getBlip().addNewExtLst().addNewExt();
ext.setUri("{96DAC541-7B7A-43D3-8B79-37D633B846F1}");
org.apache.xmlbeans.XmlCursor cursor = ext.newCursor();
cursor.toNextToken();
cursor.toNextToken();
cursor.beginElement(new javax.xml.namespace.QName("http://schemas.microsoft.com/office/drawing/2016/SVG/main", "svgBlip", "asvg"));
cursor.insertNamespace("asvg", "http://schemas.microsoft.com/office/drawing/2016/SVG/main");
cursor.insertAttributeWithValue(new javax.xml.namespace.QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "embed", "r"), svgRId);
cursor.dispose();
FileOutputStream out = new FileOutputStream("CreateExcelXSSFPictureSVG.xlsx");
workbook.write(out);
out.close();
workbook.close();
}
}
使用的扩展类:
myxssfworkbook.java
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFPictureData;
import org.apache.poi.xssf.usermodel.XSSFFactory;
import org.apache.poi.util.IOUtils;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.lang.reflect.Field;
public class MyXSSFWorkbook extends XSSFWorkbook {
public int addSVGPicture(InputStream is) throws Exception {
Field _xssfFactory = XSSFWorkbook.class.getDeclaredField("xssfFactory");
_xssfFactory.setAccessible(true);
XSSFFactory xssfFactory = (XSSFFactory)_xssfFactory.get(this);
int imageNumber = getAllPictures().size() + 1;
Field _pictures = XSSFWorkbook.class.getDeclaredField("pictures");
_pictures.setAccessible(true);
@SuppressWarnings("unchecked")
List<XSSFPictureData> pictures = (List<XSSFPictureData>)_pictures.get(this);
MyXSSFPictureData img = createRelationship(MyXSSFRelation.IMAGE_SVG, xssfFactory, imageNumber, true).getDocumentPart(); // see MyXSSFPictureData.java and MyXSSFRelation.java
try (OutputStream out = img.getPackagePart().getOutputStream()) {
IOUtils.copy(is, out);
}
pictures.add(img);
return imageNumber - 1;
}
}
import org.apache.poi.ooxml.POIXMLRelation;
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
public final class MyXSSFRelation extends POIXMLRelation {
public static final MyXSSFRelation IMAGE_SVG = new MyXSSFRelation(
"image/svg",
PackageRelationshipTypes.IMAGE_PART,
"/xl/media/image#.svg",
MyXSSFPictureData::new, MyXSSFPictureData::new // see MyXSSFPictureData.java
);
private MyXSSFRelation(String type, String rel, String defaultName,
NoArgConstructor noArgConstructor,
PackagePartConstructor packagePartConstructor) {
super(type, rel, defaultName, noArgConstructor, packagePartConstructor, null);
}
}
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xssf.usermodel.XSSFPictureData;
public class MyXSSFPictureData extends XSSFPictureData {
protected MyXSSFPictureData() {
super();
}
protected MyXSSFPictureData(PackagePart part) {
super(part);
}
}
我有一个图标列表。我想把图标的颜色改为白色。默认情况下,我的图标是黑色的。伙计们有什么建议吗?
问题内容: 我有一系列的svg矩形(使用D3.js),我想在鼠标悬停时显示一条消息,该消息应被用作背景的框包围。它们应彼此完全对齐,并与矩形(顶部和中心)完全对齐。做这个的最好方式是什么? 我尝试使用“ x”,“ y”,“ width”和“ height”属性添加svg文本,然后在svg rect之前添加。问题是文本的参考点在中间(因为我想使它居中对齐),但是对于矩形,它是左上角的坐标,而且我想在
问题内容: 我在Ubuntu 14.04的Docker 1.13.1容器中运行ASP.NET Core 1.1 Web API。 当代码尝试从HTTPS服务器检索某些数据时,出现此证书身份验证错误: HTTPS服务器是内部的,具有由公司CA签名的证书,因此请注意,我可能需要注册内部CA。 到目前为止,我已找到有关该错误的所有信息,并且Docker谈到了使Docker本身运行,连接到存储库等。我的D
问题内容: 我有一个包含图像的svg: 如何用字体真棒图标替换该行: 由于图像未显示,因此似乎无法正常工作。 问题答案: 是无效的SVG。您需要包括显示图标的实际字符。如果您查看fontawesome的样式表,您将看到… 但是那些是为CSS编码的unicode字符。在SVG中,您需要将example的语法更改为: 然后在样式表中添加:
问题内容: 我需要将SVG图形添加到PDF文件中。 使用iText7是否有可能? 使用iText5: 我在以下页面中发现了这一点: PdfPTable和PdfTemplate 有一种创建类似于Template的方法: 如何创建Graphics2D? 问题答案: 巧合的是,我们今天发布了SVG实现。我们目前尚不支持全部功能集,我们仍将在第二季度及以后的时间里进行开发,但是您已经可以使用它了。该工
我有一个灰色的选项,我必须完成才能完成一个项目。上面说