HTML 在 PDF 中嵌入图像
HTML embedded images in PDF
我使用 BIRT 创建了一个报告,一些动态字段是来自后端系统的 HTML 值,但是当我尝试生成带有 HTML 嵌入图像的 PDF 报告时 - 然后它显示: "The resource of this report item is not reachable." 而不是图像。
是否有任何解决方案可以在 PDF 中渲染嵌入的图像?它在 HTML.
中运行良好
我找到了一个解决方案,如何渲染嵌入在 HTML 内容中的 PDF 图像。问题出在 BIRT 库 ResourceLocatorWrapper class。我改变了方法:
public byte[] findResource(ModuleHandle design, String fileName, int
fileType, Map appContext);
现在它可以成功显示 PDF 中嵌入的图像和其余 HTML 内容。不需要在 BIRT jar 库中添加这个,你可以像我一样在你的项目中的 org.eclipse.birt.report.engine.util 包下添加这个 class,它应该可以正常工作。
package org.eclipse.birt.report.engine.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.birt.report.engine.i18n.MessageConstants;
import org.eclipse.birt.report.model.api.ModuleHandle;
import com.lowagie.text.ExceptionConverter;
import com.lowagie.text.pdf.codec.Base64;
public class ResourceLocatorWrapper {
private HashMap<URL, byte[]> cache;
private static final byte[] DUMMY_BYTES = new byte[0];
private static final String RESOURCE_BUNDLE = "org.eclipse.birt.report.engine.i18n.Messages";
protected static Logger logger = Logger.getLogger(ResourceLocatorWrapper.class.getName(), RESOURCE_BUNDLE);
public ResourceLocatorWrapper() {
cache = new HashMap<URL, byte[]>();
}
public void dispose() {
synchronized (cache) {
cache.clear();
cache = null;
}
}
/**
*
* @param fileName
* @param fileType
* @param appContext
* @return
*/
public byte[] findResource(ModuleHandle design, String fileName, int fileType, Map appContext) {
if (fileName.startsWith("data:")) {
final String base64Data = fileName.substring(fileName.indexOf(",") + 1);
try {
return Base64.decode(base64Data);
} catch (Exception e) {
throw new ExceptionConverter(e);
}
} else {
URL url = design.findResource(fileName, fileType, appContext);
if (url == null) {
logger.log(Level.WARNING, MessageConstants.RESOURCE_NOT_ACCESSIBLE, fileName);
return DUMMY_BYTES;
}
return findResource(url);
}
}
/**
* Finds a resource from the given URL. If the URL is not accessible, it
* will return a 0-size byte array.
*/
public byte[] findResource(URL url) {
System.out.println("findResource(URL url)");
if (url == null) {
return DUMMY_BYTES;
}
synchronized (cache) {
if (cache == null) {
return DUMMY_BYTES;
}
byte[] inBytes = cache.get(url);
if (inBytes == null) {
try {
InputStream in = url.openStream();
inBytes = getByteArrayFromInputStream(in);
in.close();
cache.put(url, inBytes);
} catch (IOException e) {
logger.log(Level.WARNING, MessageConstants.RESOURCE_NOT_ACCESSIBLE, url.toExternalForm());
cache.put(url, DUMMY_BYTES);
return DUMMY_BYTES;
}
}
return inBytes;
}
}
private byte[] getByteArrayFromInputStream(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int size = in.read(buffer);
while (size != -1) {
out.write(buffer, 0, size);
size = in.read(buffer);
}
buffer = out.toByteArray();
out.close();
return buffer;
}
}
只需将此行放在动态图像的 onCreate
元素中
importPackage(Packages.javax.imageio);
importPackage(Packages.java.io);
importPackage(Packages.sun.misc);
decoder = new BASE64Decoder();
decodedBytes = decoder.decodeBuffer(this.getRowData().getColumnValue("YOUR_DATA_BS64"));
this.data =decodedBytes;
bais = new ByteArrayInputStream( decodedBytes);
bufimg = ImageIO.read(bais);
this.setHeight(bufimg.getHeight() +"px");
this.setWidth(bufimg.getWidth() +"px");
我使用 BIRT 创建了一个报告,一些动态字段是来自后端系统的 HTML 值,但是当我尝试生成带有 HTML 嵌入图像的 PDF 报告时 - 然后它显示: "The resource of this report item is not reachable." 而不是图像。
是否有任何解决方案可以在 PDF 中渲染嵌入的图像?它在 HTML.
中运行良好我找到了一个解决方案,如何渲染嵌入在 HTML 内容中的 PDF 图像。问题出在 BIRT 库 ResourceLocatorWrapper class。我改变了方法:
public byte[] findResource(ModuleHandle design, String fileName, int fileType, Map appContext);
现在它可以成功显示 PDF 中嵌入的图像和其余 HTML 内容。不需要在 BIRT jar 库中添加这个,你可以像我一样在你的项目中的 org.eclipse.birt.report.engine.util 包下添加这个 class,它应该可以正常工作。
package org.eclipse.birt.report.engine.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.birt.report.engine.i18n.MessageConstants;
import org.eclipse.birt.report.model.api.ModuleHandle;
import com.lowagie.text.ExceptionConverter;
import com.lowagie.text.pdf.codec.Base64;
public class ResourceLocatorWrapper {
private HashMap<URL, byte[]> cache;
private static final byte[] DUMMY_BYTES = new byte[0];
private static final String RESOURCE_BUNDLE = "org.eclipse.birt.report.engine.i18n.Messages";
protected static Logger logger = Logger.getLogger(ResourceLocatorWrapper.class.getName(), RESOURCE_BUNDLE);
public ResourceLocatorWrapper() {
cache = new HashMap<URL, byte[]>();
}
public void dispose() {
synchronized (cache) {
cache.clear();
cache = null;
}
}
/**
*
* @param fileName
* @param fileType
* @param appContext
* @return
*/
public byte[] findResource(ModuleHandle design, String fileName, int fileType, Map appContext) {
if (fileName.startsWith("data:")) {
final String base64Data = fileName.substring(fileName.indexOf(",") + 1);
try {
return Base64.decode(base64Data);
} catch (Exception e) {
throw new ExceptionConverter(e);
}
} else {
URL url = design.findResource(fileName, fileType, appContext);
if (url == null) {
logger.log(Level.WARNING, MessageConstants.RESOURCE_NOT_ACCESSIBLE, fileName);
return DUMMY_BYTES;
}
return findResource(url);
}
}
/**
* Finds a resource from the given URL. If the URL is not accessible, it
* will return a 0-size byte array.
*/
public byte[] findResource(URL url) {
System.out.println("findResource(URL url)");
if (url == null) {
return DUMMY_BYTES;
}
synchronized (cache) {
if (cache == null) {
return DUMMY_BYTES;
}
byte[] inBytes = cache.get(url);
if (inBytes == null) {
try {
InputStream in = url.openStream();
inBytes = getByteArrayFromInputStream(in);
in.close();
cache.put(url, inBytes);
} catch (IOException e) {
logger.log(Level.WARNING, MessageConstants.RESOURCE_NOT_ACCESSIBLE, url.toExternalForm());
cache.put(url, DUMMY_BYTES);
return DUMMY_BYTES;
}
}
return inBytes;
}
}
private byte[] getByteArrayFromInputStream(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int size = in.read(buffer);
while (size != -1) {
out.write(buffer, 0, size);
size = in.read(buffer);
}
buffer = out.toByteArray();
out.close();
return buffer;
}
}
只需将此行放在动态图像的 onCreate
元素中
importPackage(Packages.javax.imageio);
importPackage(Packages.java.io);
importPackage(Packages.sun.misc);
decoder = new BASE64Decoder();
decodedBytes = decoder.decodeBuffer(this.getRowData().getColumnValue("YOUR_DATA_BS64"));
this.data =decodedBytes;
bais = new ByteArrayInputStream( decodedBytes);
bufimg = ImageIO.read(bais);
this.setHeight(bufimg.getHeight() +"px");
this.setWidth(bufimg.getWidth() +"px");