使用freemarker生成word、html时图片显示问题

使用freemarker生成word、html时,在图片显示这儿碰了个大钉子,最后总算弄出来了,这里总结一下。

 

1、生成word

a、使用freemarker生成word文档图片显示需要特殊处理,若是按照常理(使用占位符的形式)替换完成之后显示图片的区域只会出现一堆内容(即你给它赋值的内容)而不是一张图片。

b、如何处理:直接从某处复制一张图片放到word中需要显示的区域,然后另存为xml。打开xml文件可以发现这张图片是以base64编码存在的,且这些编码放在<w:binData>标签之中。将这些base64编码使用占位符代替然后进行常规处理就能正常显示了。

c、word中添加图片之后,xml里边就会多出一个<w:pict>标签,内容如下(以我本地的为例):

<w:pict>
<v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">
	<v:stroke joinstyle="miter"/>
	<v:formulas>
		<v:f eqn="if lineDrawn pixelLineWidth 0"/>
		<v:f eqn="sum @0 1 0"/>
		<v:f eqn="sum 0 0 @1"/>
		<v:f eqn="prod @2 1 2"/>
		<v:f eqn="prod @3 21600 pixelWidth"/>
		<v:f eqn="prod @3 21600 pixelHeight"/>
		<v:f eqn="sum @0 0 1"/>
		<v:f eqn="prod @6 1 2"/>
		<v:f eqn="prod @7 21600 pixelWidth"/>
		<v:f eqn="sum @8 21600 0"/>
		<v:f eqn="prod @7 21600 pixelHeight"/>
		<v:f eqn="sum @10 21600 0"/>
	</v:formulas>
	<v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
	<o:lock v:ext="edit" aspectratio="t"/>
</v:shapetype>
<w:binData w:name="wordml://03000001.png" xml:space="preserve">${field30}</w:binData>
<v:shape id="_x0000_i1025" type="#_x0000_t75" alt="" style="width:90.35pt;height:112.75pt">
<v:imagedata src="wordml://03000001.png" o:href="http://127.0.0.1:8080/bfp/2016/12/30/00000000001.png"/>
</v:shape>
</w:pict>
我们需要用到的是<w:binData>,这个标签中间用来显示图片内容(通常都是base64编码),也就是要使用占位符的地方,我这里用的是${field30}。

若需要调整别的可以直接修改其他标签内容。

 

d、使用java代码将图片生成base64编码:
/**
 * 该方法用来将指定的文件转换成base64编码
 * @param path:图片路径
 * **/
private String getImageStr(String path){
	//1、校验是否为空
	if(path==null || path.trim().length()<=0){return "";}
	
	//2、校验文件是否为目录或者是否存在
	File picFile = new File(path);
	if(picFile.isDirectory() || (!picFile.exists())) return "";
	
	//3、校验是否为图片
	try {  
	    BufferedImage image =ImageIO.read(picFile);  
	    if (image == null) {  
	    	return "";
	    }  
	} catch(IOException ex) { 
		ex.printStackTrace();
		return "";
	}
	
	//4、转换成base64编码
	String imageStr = "";
	try {
		byte[] data = null;
		InputStream in = new FileInputStream(path);
		data = new byte[in.available()];
		in.read(data);
		BASE64Encoder encoder = new BASE64Encoder();
		imageStr = encoder.encode(data);
	} catch (Exception e) {
		imageStr="";
		e.printStackTrace();
	}
	
	return imageStr;
}
 

2、生成html:

a、模板文件中直接使用img标签显示即可,如:<img width="120" height="150"  src="${field30}" />。

b、src中可以直接放图片的路径,也可以放base64编码。若是使用绝对路径,需要添加前缀:file:///。如图片路径为:D:/temp/1.png,那么src="file:///D:/temp/1.png"。这样子才能显示出来。缺点:因为图片通常都存在服务器端,在服务器端显示图片自然没有问题,若是放到客户端因为指定目录下没有文件那么页面中的图片自然就显示不出来了

c、使用base64编码显示图片。若是在src属性中直接加载base64编码的图片,形如:src="base64编码",这样的图片也显示不出来,还需要添加形如data:image/图片格式;base64,的前缀。如显示png格式的图片,src="data:image/png;base64,base64编码“,如此才能显示出来。(测试了一下,火狐、360、谷歌、IE11、IE8都能很好的支持,其他浏览器没测过)

 

3、生成pdf:

a、生成pdf我分成了两步:先使用freemarker生成html文件,然后使用flying saucer将html转成pdf文件。
b、直接使用“base64编码显示图片”生成的HTML文件,转成pdf时,图片会显示不出来(html文件自然是能正常显示的),具体原因未知。解决办法是采用绝对路径。先使用绝对路径的方法生成html文件中的图片,此时图片和html文件都在服务器端,图片自然能正常显示,然后将该文件转成pdf。在客户端下载下来之后,图片也能正常显示。
发布了380 篇原创文章 · 获赞 39 · 访问量 10万+
展开阅读全文

图片的二进制流通过Img控件显示html中打印出word文档为什么没有图片

04-14

我已经获取了图片的二进制,并且用BASE64进行编码,我将图片写到本地的文件中可以生成图片。 然后通过<img src=""/>这个控件把二进制写进去,生成word的时候显示不到图片。 然后我将生成的没有图片的word转换成html文件,生成的有一个files文档,里面有一张照片(image001.gif)也是没有内容,以下是督导的html中照片的保存方式: <td width=108 rowspan=4 style='width:80.95pt;border:solid windowtext 1.0pt; border-left:none;mso-border-left-alt:solid windowtext .5pt;mso-border-alt: solid windowtext .5pt;padding:0cm 2.85pt 0cm 5.4pt;height:30.55pt'> <p class=MsoNormal align=center style='text-align:center;word-break:break-all'><span style='font-size:12.0pt;font-family:楷体_GB2312;mso-hansi-font-family:宋体'>照片<span lang=EN-US><o:p></o:p></span></span></p> <p class=MsoNormal align=left style='text-align:left;mso-pagination:widow-orphan; word-break:break-all'><span lang=EN-US><!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/> </v:shapetype><v:shape id="图片_x0020_1" o:spid="_x0000_s1026" type="#_x0000_t75" alt="Base64 encoded image" style='width:81.35pt;height:103.8pt;visibility:visible; mso-wrap-style:square;mso-left-percent:-10001;mso-top-percent:-10001; mso-position-horizontal:absolute;mso-position-horizontal-relative:char; mso-position-vertical:absolute;mso-position-vertical-relative:line; mso-left-percent:-10001;mso-top-percent:-10001'> <w:wrap type="none"/> <w:anchorlock/> </v:shape><![endif]--><![if !vml]><img width=108 height=138 src="ZTE2liu.files/image001.gif" alt="Base64 encoded image" v:shapes="图片_x0020_1"><![endif]></span><span lang=EN-US style='font-size:12.0pt;font-family:宋体;mso-bidi-font-family:宋体; mso-font-kerning:0pt'><o:p></o:p></span></p> </td> 难道这个二进制流不能直接写到<img src="">中吗?挺着急的求大神指导 我邮箱 zhykwork@163.com 谢谢! 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览