SvgSaveOptions saveOptions = new SvgSaveOptions();
saveOptions.setResourcesFolder(“folder”)
这样会把图片保存到磁盘里面。会多两次IO时间,读取的时候也不好控制时序。
能不能存入内存对象,例如BufferedImage
您可以通过实现 IResourceSavingCallback并为每个资源文件使 ResourceSavingArgs.ResourceStream 来实现这一目标。
public static void main(String[] args) throws Exception {
Document doc = new Document("test.docx");
ResourceSavingCallback callback = new ResourceSavingCallback();
SvgSaveOptions opts = new SvgSaveOptions();
opts.setResourceSavingCallback(callback);
doc.save("test.svg", opts);
for (var res : callback.getResources().entrySet()) {
String filename = res.getKey();
ByteArrayOutputStream stream = res.getValue();
var inputStream = new ByteArrayInputStream(stream.toByteArray());
if (filename.endsWith(".jpeg")) {
BufferedImage image = ImageIO.read(inputStream);
// 资源文件已读入 BufferedImage
}
}
}
private static class ResourceSavingCallback implements IResourceSavingCallback {
HashMap<String,ByteArrayOutputStream> resources = new HashMap<String, ByteArrayOutputStream>();
@Override
public void resourceSaving(ResourceSavingArgs args) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
args.setResourceStream(out);
resources.put(args.getResourceFileName(), out);
}
public HashMap<String, ByteArrayOutputStream> getResources() {
return resources;
}
}
非常感谢您的回复,使用您的方法解决了两次IO的问题,但是由于我这边图片的来自其他的业务系统。耗时比较长。获取到业务系统图片之后,用AlternativeText中的标记来替换图片
shapes = doc.getChildNodes(NodeType.Shape, true);
for (Shape nshape : shapes)
{
switch( nshape.AlternativeText)
{
case “img1”:
nshape.ImageData.SetImage(@“d:\img3.png”);
break;
case “img2”:
nshape.ImageData.SetImage(@“d:\img4.png”);
break;
}
}
耗时较长,用户会在前端长时间等待,有没有什么办法可以让我先返回svg,然后再换掉这些图片呢。
现在的问题是ResourceSavingArgs 丢失了shape的AlternativeText。在aspose保存图片的时候的文件名也没找到和shape之间的映射关系
以下是我的错误做法。好像document.save之后再nshape.ImageData.SetImage已经不能修改图片了
@RequestMapping(value = "/preview")
@ResponseBody
public void docPreview(HttpServletRequest req, HttpServletResponse res) throws Exception {
shapes = document.getChildNodes(NodeType.Shape, true);
//另起线程根据AlternativeText获取图片
new Thread(() -> {
for (Shape nshape : shapes)
{
switch( nshape.AlternativeText)
{
case "img1":
nshape.ImageData.SetImage("来自业务系统的图片1");
break;
case "img2":
nshape.ImageData.SetImage("来自业务系统的图片2");
break;
}
}
}).start();
//在这里先返回svg到前端展示,避免用户长时间等待
document.save(res.getOutputStream(), saveOptions);
}
@RequestMapping(value = "/docResources/{fileName}")
@ResponseBody
public void docResources(HttpServletRequest req, HttpServletResponse res, @PathVariable String fileName) throws InterruptedException {
//在这里二次请求获取图片
File file = new File("doc/docResources/"+fileName));
try {
InputStream is = new FileInputStream(file);
OutputStream output = res.getOutputStream();
Utils.copyBinaryTo(is, output);
output.flush();
output.close();
is.close();
} catch (Exception exp) {
getLogger().error("get doc resources failed", exp);
}
}
@Jimmy.Zhengming, 不幸的是,API不允许在形状内部的图像和 ResourceSavingArgs 中的图像之间进行映射。
您可以上传示例文档吗? 可能这可能会帮助我为这种情况找到解决方法。