富文本带图片导出word

java 将富文本编辑器中的内容导出word,包含图片、表格等标签

思路就是将富文本编辑器中的内容转换为html标签,在后台使用ftl格式的模板替换占位符信息,需要注意的是html中的图片的标签是img,但是word并不认img标签,而且有些图片只是一个引用地址,在别的机器上就无法正常显示。所以要对图片解析为base64字符串,再填充到模板上。

引入依赖

<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.31</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.15.1</version>
</dependency>


制作模板

制作模板时要用word,不要用wps!!!
在这里插入图片描述
${xxx}即为占位符标签
将word文件另存为.mht文件
在这里插入图片描述
然后将.mht后缀名改为ftl,使用文本编辑器打开ftl文件
在这里插入图片描述
将模板中的字符(例如:姓名:,性别:,简介:)转换为3Dus-asci,十进制Accsii码(方法在后面的WordHtmlGeneratorHelper工具类中),不然无法正常显示。

全文检索gb2312把他改成utf-8,同时需要加上3D前缀
在这里插入图片描述

占 位 符 中 间 会 生 成 一 些 其 他 字 符 需 要 将 其 他 扰 乱 信 息 去 掉 只 保 留 占 位 符 , 比 如 {}占位符 中间会生成一些其他字符 需要将其他扰乱信息去掉 只保留占位符,比如 {sex}另存为mht文件后,可能成了 s e = x 这 个 格 式 , 需 手 动 再 修 改 一 下 。 只 保 留 {se= x}这个格式,需手动再修改一下。只保留 se=x{sex},其中的样式标签也全部删除。
在这里插入图片描述
1.添加 ${imagesBase64String!“”} 标识 在folHlink下面添加 该标识 存放图片base64信息
2.添加 ${imagesXmlHrefString!“”} 标识 在filelist.xml 上面添加 该标识 存放图片base64的链接信息
其实添加的 i m a g e s B a s e 64 S t r i n g 和 {imagesBase64String}和 imagesBase64String{imagesXmlHrefString}标识 就是 首先定义一个图片的base64,然后在下面引用,随后在正文中 直接调用图片的引用即可。
记住这三处标识 【NextPart_ 和 Content-Location】 这里文档 全都是一样的 所以在生成图片base64定义时 也要保持一致

看一下图片 image004.jpg

图片base64的定义
在这里插入图片描述
图片链接的引用
在这里插入图片描述
图片的显示 调用图片链接的引用 <v:shape>xxxxx</v:shape>及后面的 这些是页面显示的图片 需要动态生成
在这里插入图片描述
富文本存储的形式 为base64,而不是存储图片的地址,所以需要先根据base64生成图片 在进行操作。

Base64FileTypeEnum

public enum Base64FileTypeEnum {

    // 文件类型
    BASE64_FILETYPE_DOC(".doc","data:application/msword;base64"),
    BASE64_FILETYPE_DOCX(".docx","data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64"),
    BASE64_FILETYPE_XLS(".xls","data:application/vnd.ms-excel;base64"),
    BASE64_FILETYPE_XLSX(".xlsx","data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64"),
    BASE64_FILETYPE_PDF(".pdf","data:application/pdf;base64"),
    BASE64_FILETYPE_PPT(".ppt","data:application/vnd.ms-powerpoint;base64"),
    BASE64_FILETYPE_PPTX(".pptx","data:application/vnd.openxmlformats-officedocument.presentationml.presentation;base64"),
    BASE64_FILETYPE_TXT(".txt","data:txt/plain;base64"),
    // 图片类型
    BASE64_FILETYPE_PNG(".png","data:image/png;base64"),
    BASE64_FILETYPE_JPG(".jpg","data:image/jpg;base64"),
    BASE64_FILETYPE_JPEG(".jpeg","data:image/jpeg;base64"),
    BASE64_FILETYPE_GIF(".gif","data:image/gif;base64"),
    BASE64_FILETYPE_SVG(".svg","data:image/svg+xml;base64"),
    BASE64_FILETYPE_ICO(".ico","data:image/x-icon;base64"),
    BASE64_FILETYPE_BMP(".bmp","data:image/bmp;base64"),
    ;


    private String code;
    private String value;

    public String getCode(){return code;}
    public String getValue(){return value;}

    private Base64FileTypeEnum(String code,String value){
        this.code = code;
        this.value = value;
    }
    public static String getFileType(String value) {
        Base64FileTypeEnum[] types = values();
        for(Base64FileTypeEnum x : types){
            if(x.getValue().equals(value)){
                return x.getCode();
            }
        }
        return null;
    }
}

64位转文件工具类 Base64ToFileUtil


import sun.misc.BASE64Decoder;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;


public class Base64ToFileUtil {

    public static void base64ToFile(String fileType,String destPath,String base64,String fileName){
        File file = null;
        // 创建文件目录
        String filePath = destPath;
        File dir = new File(filePath);
        if(!dir.exists() && !dir.isDirectory()){
            dir.mkdirs();
        }
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        try {
            // 截取base64头部,获取文件类型
//            String fileType = Base64FileTypeEnum.getFileType(base64.substring(0,base64.indexOf(",")));
            // 去掉头部,防止转换文件后打开显示文件损坏
            String s = base64.substring(base64.indexOf(",")+1);
            byte[] bytes = new BASE64Decoder().decodeBuffer(s);
            file = new File(filePath + "\\" + fileName );
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(bos != null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

删除单个文件


import java.io.File;

public class FolderUtil {
 
    //删除单个文件
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                System.out.println("删除单个文件" + fileName + "成功!");
                return true;
            } else {
                System.out.println("删除单个文件" + fileName + "失败!");
                return false;
            }
        } else {
            System.out.println("删除单个文件失败:" + fileName + "不存在!");
            return false;
        }
    }
}

RichHtmlHandler


import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class RichHtmlHandler {

    private Document doc = null;
    private String html;

    private String docSrcParent = "";
    private String docSrcLocationPrex = "";
    private String nextPartId;
    private String shapeidPrex;
    private String spidPrex;
    private String typeid;

	// 从http下载的图片的临时存储位置,最后记得删除
    private  String imgFilePath = "C:\\disk\\train\\img";
    private String handledDocBodyBlock;
    private List<String> docBase64BlockResults = new ArrayList<String>();
    private List<String> xmlImgRefs = new ArrayList<String>();
    //存储临时图片 方便后续删除
    private List<String> photoNameList=new ArrayList<>(); 

    public List<String> getPhotoNameList() {
        return photoNameList;
    }

    public String getDocSrcLocationPrex() {
        return docSrcLocationPrex;
    }

    public void setDocSrcLocationPrex(String docSrcLocationPrex) {
        this.docSrcLocationPrex = docSrcLocationPrex;
    }

    public String getNextPartId() {
        return nextPartId;
    }

    public void setNextPartId(String nextPartId) {
        this.nextPartId = nextPartId;
    }

    public String getHandledDocBodyBlock() {
        String raw=   WordHtmlGeneratorHelper.string2Ascii(doc.getElementsByTag("body").html());
        return raw.replace("=3D", "=").replace("=", "=3D");
    }

    public String getRawHandledDocBodyBlock() {
        String raw=  doc.getElementsByTag("body").html();
        return raw.replace("=3D", "=").replace("=", "=3D");
    }
    public List<String> getDocBase64BlockResults() {
        return docBase64BlockResults;
    }

    public List<String> getXmlImgRefs() {
        return xmlImgRefs;
    }

    public String getShapeidPrex() {
        return shapeidPrex;
    }

    public void setShapeidPrex(String shapeidPrex) {
        this.shapeidPrex = shapeidPrex;
    }

    public String getSpidPrex() {
        return spidPrex;
    }

    public void setSpidPrex(String spidPrex) {
        this.spidPrex = spidPrex;
    }

    public String getTypeid() {
        return typeid;
    }

    public void setTypeid(String typeid) {
        this.typeid = typeid;
    }

    public String getDocSrcParent() {
        return docSrcParent;
    }

    public void setDocSrcParent(String docSrcParent) {
        this.docSrcParent = docSrcParent;
    }

    public String getHtml() {
        return html;
    }

    public void setHtml(String html) {
        this.html = html;
    }

    public RichHtmlHandler(String html) {
        doc = Jsoup.parse(	wrappHtml(html));
    }

    public void re_init(String html){
        doc=null;
        doc = Jsoup.parse(wrappHtml(html));
        docBase64BlockResults.clear();
        xmlImgRefs.clear();
    }

    /**
     * @Description: 获得已经处理过的HTML文件
     * @param @return
     * @return String
     * @throws IOException
     * @throws
     */
    public void handledHtml(boolean isWebApplication,String filePath)
            throws IOException {
        List<String> photoNames=new ArrayList<>();
        Elements imags = doc.getElementsByTag("img");

        if (imags == null || imags.size() == 0) {
            // 返回编码后字符串
            return;
        }

        for (Element item : imags) {
            // 把文件取出来
            String src = item.attr("src");
            File imageFile = null;
            String fileTypeName="jpg";
            //图片的UUID
            String uuid = UUID.randomUUID().toString().replaceAll("-",""); 
            // 64位编码信息
            String base64Content="";
            String srcRealPath = "";
            // 先将图片下载到本地
            String fileName = src.substring(src.lastIndexOf("/")+1);
            String fileType = fileName.substring(fileName.lastIndexOf(".")+1);
            String imgFileUrl = WordImageConvertor.downLoadFormUrl(src,fileName,imgFilePath);
            String imgBase64Content = WordImageConvertor.imageToBase64(WordImageConvertor.downLoadFormUrl(src,fileName,imgFilePath));
//            src = "data:image/png;base64," + imgBase64Content;
            /*if(src.contains("base64")){
//				src="D:\\1.png";
                //将base64转换为图片file 存储到本地路径
                String[] split = src.split("base64,");
                if (split != null && split.length == 2) {
                    if(split[0].contains("/")){
//                        fileTypeName=split[0].substring(split[0].indexOf("/")+1,split[0].length()-1);
                        fileTypeName=fileType;
                    }
//                    base64Content= split[1];
                    base64Content= imgBase64Content;
                    String photoName=uuid+"."+fileTypeName;
//                    Base64ToFileUtil.base64ToFile(filePath,base64Content,photoName);
                    imageFile=new File(imgFileUrl);
                    if(imageFile.exists()){
                        photoNames.add(photoName);
                        srcRealPath=imgFileUrl;
                        item.attr("src",srcRealPath);
                    }
                }
            }*/
            base64Content= imgBase64Content;
            String photoName=uuid+"."+fileType;
            Base64ToFileUtil.base64ToFile(fileType,filePath,imgBase64Content,photoName);
            imageFile=new File(filePath + "\\" + photoName);
            if(imageFile.exists()){
                photoNames.add(filePath + "\\" + photoName);
                srcRealPath=filePath + "\\" + photoName;
                item.attr("src",srcRealPath);
            }

            String imageFileShortName = imageFile.getName();
            String docFileName = "image" + uuid + "."+ fileType;
            String srcLocationShortName = docSrcParent + "/" + docFileName;

            String styleAttr = item.attr("style"); // 样式

            int imageHeight = 0;
            int imageWidth = 0;

            // 得到文件的word mht的body块
            String handledDocBodyBlock = WordImageConvertor.toDocBodyBlock(srcRealPath,
                    imageFileShortName, imageHeight, imageWidth,styleAttr,
                    srcLocationShortName, shapeidPrex, spidPrex, typeid);

            item.parent().append(handledDocBodyBlock);
//            item.after(handledDocBodyBlock);
            item.remove();
            // 去替换原生的html中的imag

            String contextLoacation = docSrcLocationPrex + "/" + docSrcParent
                    + "/" + docFileName;

            String docBase64BlockResult = WordImageConvertor
                    .generateImageBase64Block(nextPartId, contextLoacation,
                            fileTypeName, base64Content);
            docBase64BlockResults.add(docBase64BlockResult);

            String imagXMLHref = "<o:File HRef=3D\"" + docFileName + "\"/>";
            xmlImgRefs.add(imagXMLHref);

        }
        photoNameList=photoNames;

    }

    private String getStyleAttrValue(String style, String attributeKey) {
        if (StringUtils.isEmpty(style)) {
            return "";
        }

        // 以";"分割
        String[] styleAttrValues = style.split(";");
        for (String item : styleAttrValues) {
            // 在以 ":"分割
            String[] keyValuePairs = item.split(":");
            if (attributeKey.equals(keyValuePairs[0])) {
                return keyValuePairs[1];
            }
        }

        return "";
    }

    private String wrappHtml(String html){
        // 因为传递过来都是不完整的doc
        StringBuilder sb = new StringBuilder();
        sb.append("<html>");
        sb.append("<body>");
        sb.append(html);

        sb.append("</body>");
        sb.append("</html>");
        return sb.toString();
    }

}

WordGeneratorWithFreemarker


import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.io.*;
import java.util.Map;

public class WordGeneratorWithFreemarker {
    private static Configuration configuration = null;
    private static final String FTL_FP = "classpath:/template"; //模板路径
    
    static {  
        configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");  
        configuration.setClassicCompatible(true);
        configuration.setClassForTemplateLoading(WordGeneratorWithFreemarker.class, FTL_FP);
        try {
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = resolver.getResources("template");
            Resource resource = resources[0];
//            configuration.setDirectoryForTemplateLoading(new File("D:/jsrdlgd/train-software-server/src/main/resources/template"));
            configuration.setDirectoryForTemplateLoading(resource.getFile());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }  
  
    private WordGeneratorWithFreemarker() {  
        
    }  
  
    public static void createDoc(Map<String, Object> dataMap, String templateName, OutputStream out) throws Exception{
    	Template t = configuration.getTemplate(templateName);
		
    	WordHtmlGeneratorHelper.handleAllObject(dataMap);
 
        Writer w=null;
        try {  
            // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开  
            w = new OutputStreamWriter(out);
            t.process(dataMap, w);
 
        } catch (Exception ex) {  
            ex.printStackTrace();  
            throw new RuntimeException(ex);  
        }finally {
            if(w!=null){
                w.close();
            }
        }
        return ;  
    }
    
}  

WordHtmlGeneratorHelper


import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class WordHtmlGeneratorHelper  {
	
	/**   
	* @Description: 将字符换成3Dus-asci,十进制Accsii码
	* @param @param source
	* @param @return    
	* @return String    
	* @throws
	*/
	public static String string2Ascii(String source){
		if(source==null || source==""){
			return null;
		}
		StringBuilder sb=new StringBuilder();
		
		char[] c=source.toCharArray();
		for(char item : c){
			String itemascii="";
			if(item>=19968 && item<40623){
				itemascii=itemascii="&#"+(item & 0xffff)+";";
			}else{
				itemascii=item+"";
			}
			sb.append(itemascii);
		}
		
		return sb.toString();
		
	}
	
	/**   
	* @Description: 将object的所有属性值转成成3Dus-asci编码值
	* @param @param object
	* @param @return    
	* @return T    
	* @throws
	*/
	public static <T extends Object> T handleObject2Ascii(final T toHandleObject){
		
		class myFieldsCallBack  implements ReflectionUtils.FieldCallback {
 
			@Override
			public void doWith(Field f) throws IllegalArgumentException,
					IllegalAccessException {
				if(f.getType().equals(String.class)){
					//如果是字符串类型
					f.setAccessible(true);
					String oldValue=(String)f.get(toHandleObject);
					if(!StringUtils.isEmpty(oldValue)){
						f.set(toHandleObject, string2Ascii(oldValue));
					}
					
					//f.setAccessible(false);
				}
			}
		}
	
		ReflectionUtils.doWithFields(toHandleObject.getClass(), new myFieldsCallBack());
		
		return toHandleObject;
	}
	
	
	public static <T extends Object> List<T> handleObjectList2Ascii(final List<T> toHandleObjects){
		
		for (T t : toHandleObjects) {
			handleObject2Ascii(t);
		}
		
		return toHandleObjects;
	}
	
	
	public static void handleAllObject(Map<String, Object> dataMap){
		
		//去处理数据
    	for (Map.Entry<String, Object> entry : dataMap.entrySet()){
    		Object item=entry.getValue();
    		
    		//判断object是否是primitive type 
    		if(isPrimitiveType(item.getClass())){
    			if(item.getClass().equals(String.class)){
    				item=WordHtmlGeneratorHelper.string2Ascii((String)item);
    				entry.setValue(item);
    			}
    		}else if(isCollection(item.getClass())){
    			for (Object itemobject : (Collection)item) {
    				WordHtmlGeneratorHelper.handleObject2Ascii(itemobject);
				}
    		}else{
    			WordHtmlGeneratorHelper.handleObject2Ascii(item);
    		}
    	}
		
	}

	public static void main(String[] args) {
		System.out.println(string2Ascii("一"));
	}
	
	public static String joinList(List<String> list,String join ){
		StringBuilder sb=new StringBuilder();
		for (String t : list) {
			sb.append(t);
			if(!StringUtils.isEmpty(join)){
				sb.append(join);
			}
		}
		
		return sb.toString();
	} 
	
	
	private static boolean isPrimitiveType(Class<?> clazz){
    	return clazz.isEnum() ||
		CharSequence.class.isAssignableFrom(clazz) ||
		Number.class.isAssignableFrom(clazz) ||
		Date.class.isAssignableFrom(clazz);
    	
    }
    private static boolean isCollection(Class<?> clazz){
    	return Collection.class.isAssignableFrom(clazz);
    }
 
	
}

WordImageConvertor


import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.UUID;

public class WordImageConvertor {
 
 
    /**
     * @param @param  imageSrc 文件路径
     * @param @return
     * @return String
     * @throws IOException
     * @throws
     * @Description: 将图片转换成base64编码的字符串
     * @author:LiaoFei
     * @date:2016-3-28 上午11:22:26
     */
    public static String imageToBase64(String imageSrc) throws IOException {
        //判断文件是否存在
        File file = new File(imageSrc);
        if (!file.exists()) {
            throw new FileNotFoundException("文件不存在!");
        }
        StringBuilder pictureBuffer = new StringBuilder();
        FileInputStream input = new FileInputStream(file);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 
        //读取文件
        Base64 base64 = new Base64();
        BASE64Encoder encoder = new BASE64Encoder();
        byte[] temp = new byte[1024];
        for (int len = input.read(temp); len != -1; len = input.read(temp)) {
            out.write(temp, 0, len);
        }
        pictureBuffer.append(new String(base64.encodeBase64Chunked(out.toByteArray())));
 
		out.close();
        input.close();
 
        return pictureBuffer.toString();
    }
 
 
    public static String toDocBodyBlock(
            String imageFilePath,
            String imageFielShortName,
            int imageHeight,
            int imageWidth,
            String imageStyle,
            String srcLocationShortName,
            String shapeidPrex, String spidPrex, String typeid) {
        //shapeid
        //mht文件中针对shapeid的生成好像规律,其内置的生成函数没法得知,但是只要保证其唯一就行
        //这里用前置加32位的uuid来保证其唯一性。
        String shapeid = shapeidPrex;
        shapeid += UUID.randomUUID().toString();
 
        //spid ,同shapeid处理
        String spid = spidPrex;
        spid += UUID.randomUUID().toString();
		
		
	/*	<!--[if gte vml 1]><v:shape id=3D"_x56fe__x7247__x0020_0" o:spid=3D"_x0000_i10=
				26"
				   type=3D"#_x0000_t75" alt=3D"725017921264249223.jpg" style=3D'width:456.7=
				5pt;
				   height:340.5pt;visibility:visible;mso-wrap-style:square'>
				   <v:imagedata src=3D"file9462.files/image001.jpg" o:title=3D"725017921264=
				249223"/>
				  </v:shape><![endif]--><![if !vml]><img width=3D609 height=3D454
				  src=3D"file9462.files/image002.jpg" alt=3D725017921264249223.jpg v:shapes=
				=3D"_x56fe__x7247__x0020_0"><![endif]>*/
        StringBuilder sb1 = new StringBuilder();
 
        sb1.append(" <!--[if gte vml 1]>");
        sb1.append("<v:shape id=3D\"" + shapeid + "\"");
        sb1.append("\n");
        sb1.append(" o:spid=3D\"" + spid + "\"");
        sb1.append(" type=3D\"" + typeid + "\" alt=3D\"" + imageFielShortName + "\"");
        sb1.append("\n");
        sb1.append(" style=3D' " + generateImageBodyBlockStyleAttr(imageFilePath, imageHeight, imageWidth) + imageStyle + "'");
        sb1.append(">");
        sb1.append("\n");
        sb1.append(" <v:imagedata src=3D\"" + srcLocationShortName + "\"");
        sb1.append("\n");
        sb1.append(" o:title=3D\"" + imageFielShortName.split("\\.")[0] + "\"");
        sb1.append("/>");
        sb1.append("</v:shape>");
        sb1.append("<![endif]-->");
 
        //以下是为了兼容游览器显示时的效果,但是如果是纯word阅读的话没必要这么做。
        StringBuilder sb2 = new StringBuilder();
        sb2.append(" <![if !vml]>");
 
        sb2.append("<img width=3D" + imageWidth + " height=3D" + imageHeight +
                " src=3D\"" + srcLocationShortName + "\" alt=" + imageFielShortName +
                " v:shapes=3D\"" + shapeid + "\">");
 
        sb2.append("<![endif]>");
 
        return sb1.toString() + sb2.toString();
//		return sb1.toString();
    }
 
    /**
     * @param @param  nextPartId
     * @param @param  contextLoacation
     * @param @param  ContentType
     * @param @param  base64Content
     * @param @return
     * @return String
     * @throws
     * @Description: 生成图片的base4块
     */
    public static String generateImageBase64Block(String nextPartId, String contextLoacation,
                                                  String fileTypeName, String base64Content) {
		/*--=_NextPart_01D188DB.E436D870
				Content-Location: file:///C:/70ED9946/file9462.files/image001.jpg
				Content-Transfer-Encoding: base64
				Content-Type: image/jpeg
				
				base64Content
		*/
 
        StringBuilder sb = new StringBuilder();
        sb.append("\n");
        sb.append("\n");
        sb.append("------=_NextPart_" + nextPartId);
        sb.append("\n");
        sb.append("Content-Location: " + contextLoacation);
        sb.append("\n");
        sb.append("Content-Transfer-Encoding: base64");
        sb.append("\n");
        sb.append("Content-Type: " + getImageContentType(fileTypeName));
        sb.append("\n");
        sb.append("\n");
        sb.append(base64Content);
 
        return sb.toString();
    }
 
 
    private static String generateImageBodyBlockStyleAttr(String imageFilePath, int height, int width) {
        StringBuilder sb = new StringBuilder();
 
        BufferedImage sourceImg;
        FileInputStream fileInputStream=null;
        try {
            fileInputStream  = new FileInputStream(imageFilePath);
            sourceImg = ImageIO.read(fileInputStream);
            if (height == 0) {
                height = sourceImg.getHeight();
            }
            if (width == 0) {
                width = sourceImg.getWidth();
            }
 
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fileInputStream!=null){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
 
        System.out.println("图片高度"+height+"图片宽度"+width);
 
 
        if(height>300){
            height=300;
        } if(width>500){
            width=500;
        }
 
        //将像素转化成pt
        BigDecimal heightValue = new BigDecimal(height * 12 / 16);
        heightValue = heightValue.setScale(2, BigDecimal.ROUND_HALF_UP);
        BigDecimal widthValue = new BigDecimal(width * 12 / 16);
        widthValue = widthValue.setScale(2, BigDecimal.ROUND_HALF_UP);
 
        sb.append("height:" + heightValue + "pt;");
        sb.append("width:" + widthValue + "pt;");
        sb.append("visibility:visible;");
        sb.append("mso-wrap-style:square; ");
 
 
        return sb.toString();
    }
 
    private static String getImageContentType(String fileTypeName) {
        String result = "image/jpeg";
        //http://tools.jb51.net/table/http_content_type
        if (fileTypeName.equals("tif") || fileTypeName.equals("tiff")) {
            result = "image/tiff";
        } else if (fileTypeName.equals("fax")) {
            result = "image/fax";
        } else if (fileTypeName.equals("gif")) {
            result = "image/gif";
        } else if (fileTypeName.equals("ico")) {
            result = "image/x-icon";
        } else if (fileTypeName.equals("jfif") || fileTypeName.equals("jpe")
                || fileTypeName.equals("jpeg") || fileTypeName.equals("jpg")) {
            result = "image/jpeg";
        } else if (fileTypeName.equals("net")) {
            result = "image/pnetvue";
        } else if (fileTypeName.equals("png") || fileTypeName.equals("bmp")) {
            result = "image/png";
        } else if (fileTypeName.equals("rp")) {
            result = "image/vnd.rn-realpix";
        } else if (fileTypeName.equals("rp")) {
            result = "image/vnd.rn-realpix";
        }
 
        return result;
    }

 
 /**
 * 从http地址下载图片
 */
    public static String downLoadFormUrl(String urlStr,String fileName,String savePath){
        try {
            String filename = fileName.substring(0,fileName.lastIndexOf("."));
            // 将中文转码
            URL url = new URL(urlStr.replace(filename, URLEncoder.encode(filename,"utf-8")));
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            // 设置超时时间为3秒
            conn.setConnectTimeout(3*1000);
            InputStream inputStream = conn.getInputStream();
            byte[] getData = readInputStream(inputStream);
            File saveDir = new File(savePath);
            if(!saveDir.exists()){
                saveDir.mkdirs();
            }
            File file = new File(saveDir+File.separator+fileName);
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(getData);
            if(fos!=null){
                fos.close();
            }
            if(inputStream!=null){
                inputStream.close();
            }
            return saveDir+File.separator+fileName;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
    public static byte[] readInputStream(InputStream inputStream) throws Exception{
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1){
            bos.write(buffer,0,len);
        }
        bos.close();
        return bos.toByteArray();
    }
 
}

测试

		//临时图片信息
		List<String> photoNameList = new ArrayList<>();
		// 图片占位符
        String handlerBase64Block = "";
        // 图片占位符
        String xmlimaHref = "";
        String fileName = "测试";
        Map<String,Object> map = new HashMap();
        // 有几个富文本就要写几遍,多个图片信息要累加
		Triple<String,String,String> nameBody = getHtmlBodyBlock((StringUtils.isNotBlank(organizationName) ? organizationName :""),filePath,handlerBase64Block,xmlimaHref,photoNameList);
        handlerBase64Block = nameBody.getMiddle();
        xmlimaHref = nameBody.getRight();
        map.put("name",nameBody.getLeft());

        Triple<String,String,String> sexBody = getHtmlBodyBlock((StringUtils.isNotBlank(planName) ? planName :""),filePath,handlerBase64Block,xmlimaHref,photoNameList);
        handlerBase64Block = sexBody.getMiddle();
        xmlimaHref = sexBody.getRight();
        map.put("sex",sexBody.getLeft());

        Triple<String,String,String> introductionBody = getHtmlBodyBlock((StringUtils.isNotBlank(vo.getIntroduction()) ? vo.getIntroduction() :""),filePath,handlerBase64Block,xmlimaHref,photoNameList);
        handlerBase64Block = introductionBody.getMiddle();
        xmlimaHref = introductionBody.getRight();
        map.put("introductory",introductionBody.getLeft());
		map.put("imagesBase64String",handlerBase64Block);
        map.put("imagesXmlHrefString",xmlimaHref);
        OutputStream os = null;
        //导出word
        try {
            os = response.getOutputStream();
            response.reset();
            response.setCharacterEncoding("utf-8");
            //导出为docx格式
            response.setContentType("application/msword");
//                response.setHeader("Content-Disposition", "attachment; filename=" + "考评总结");
            response.setHeader("Content-Disposition", "attachment;filename*=" +
                    URLEncoder.encode(fileName, "UTF-8") +".doc");
//            byte[] b = templeteContent.getBytes("UTF-8");
//            os.write(b);
          		WordGeneratorWithFreemarker.createDoc(map,"ass.ftl",os);
          		//删除临时图片
            if(photoNameList != null &&photoNameList.size() > 0){
                for(String photoName:photoNameList){
                    if(photoName != null && !"".equals(photoName)){
                        FolderUtil.deleteFile(photoName);
                    }
                }
            }
            } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.flush();
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }



/**
     * 获得转换后的str
     * @param str
     * @param filePath
     * @param handlerBase64Block
     * @param xmlimaHref
     * @return
     */
    private Triple<String,String,String> getHtmlBodyBlock(String str, String filePath, String handlerBase64Block, String xmlimaHref, List<String> photoNameList){
        RichHtmlHandler handler = new RichHtmlHandler( str);
        handler.setDocSrcLocationPrex("file:///C:/65153585");
        handler.setDocSrcParent("kaopingzongjie.files");
        handler.setNextPartId("01D875D5.98BBADB0");
        handler.setShapeidPrex("_x56fe_x7247_x0020");
        handler.setSpidPrex("_x0000_i");
        handler.setTypeid("#_x0000_t75");
        try {
            handler.handledHtml(false,filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(handler.getDocBase64BlockResults() != null && handler.getDocBase64BlockResults().size() >0){
            for(String item : handler.getDocBase64BlockResults()){
                handlerBase64Block += item+"\n";
            }
        }


        if(handler.getXmlImgRefs() != null && handler.getXmlImgRefs().size() > 0){
            for(String item : handler.getXmlImgRefs()){
                xmlimaHref += item+"\n";
            }
        }
        photoNameList.addAll(handler.getPhotoNameList());
        return Triple.of(handler.getHandledDocBodyBlock(), handlerBase64Block, xmlimaHref);
    }
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值