HTML转word_讯飞语记怎么变成word文档

HTML转word_讯飞语记怎么变成word文档HTML转word背景介绍1.使用POI进行转化1.1思路1.2代码示例1.3思考2.使用jacob进行转化2.1思路2.2代码示例2.3思考3.总结背景介绍业务:将平台中尽调笔记(富文本)以word形式导出。1.使用POI进行转化依赖jarpoi-3.17.jarpoi-excelant-3.17.jarpoi-ooxml-3.17.jarpoi-ooxml-…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

背景介绍

业务:将平台中笔记(富文本)以word形式导出。

1. 使用POI进行转化

依赖jar
poi-3.17.jar
poi-excelant-3.17.jar
poi-ooxml-3.17.jar
poi-ooxml-schemas-3.17.jar
jsoup-1.11.3.jar

1.1 思路

a). 获取HTML
b). HTML标准化
c). 转化

1.2 代码示例

/**
  * HTML转word
  *
  * @param noteName 导出文件名称
  * @paramre portDirName 文件路径
  * @param researchNoteInfo 文件的html
  * @return void
  * @author Solitary
  * @date 2019/1/11 9:21
  */
public static void htmlToWord(String noteName, String reportDirName, String researchNoteInfo) throws Exception {
     //拼一个标准的HTML格式文档
    Document document = Jsoup.parse(researchNoteInfo);
    FileUtils.fileIsExist(reportDirName);
    InputStream is = new ByteArrayInputStream(document.html().getBytes("GBK"));
    OutputStream os = new FileOutputStream(reportDirName+noteName);
    inputStreamToWord(is, os);
}
    
/**
 * 把is写入到对应的word输出流os中
 *
 * @param is
 * @param os
 * @throws IOException
 */
private static void inputStreamToWord(InputStream is, OutputStream os) throws IOException {
    POIFSFileSystem fs = new POIFSFileSystem();
    DirectoryNode root = fs.getRoot();
    root.createDocument("WordDocument", is);
    fs.writeFilesystem(os);
    os.close();
    is.close();
}

1.3 思考

使用poi进行HTML转word的确很简单的,但是一个很棘手的问题就是当图片资源失效、断网的情况下,word的图片无法显示。所以使用这种方式转word显得有点鸡肋了。

2. 使用jacob进行转化

依赖jar
jacob.jar
jsoup-1.11.3.jar

2.1 思路

a). 标准化HTML
b). 下载图片资源到本地
c). 替换所有img标签为<p>${img_imgName}</p>
d). 将替换后的HTML写入空白文档doc中
e). 复制上一步写入文档的内容,替换所有${img_imgName}为本地图片路径
f). 另存为doc文件

2.2 代码示例

/**
 * 创建空白文档_写入html_处理空白文档image_复制空白文档至最终文档
 * 
 * @param imgs
 * @param html
 * @param localpath
 */
 public static String getWord(String html, String localpath, long researchId) {
     // 下载图片到本地 略
     // 图片在文档中的键${name} - 值图片的绝对路径    imgMap.put("${ABC}", localpath + "\\ABC.png");
     Map<String, String> imgMap = new HashMap<String, String>();
     // 解析html_创建空白文档_html写入空白文档
     Document document = Jsoup.parse(html);
     for (Element element : document.body().select("body > *")) {
     	sysElementText(element, localpath, imgMap);
	 }
     createWord(localpath, "blank");
     File doc = new File(localpath + File.separator + "blank.doc");
     FileWriter fw;
     try {
         fw = new FileWriter(doc);
         fw.write(document.html(), 0, document.html().length());// 写入文件
         fw.flush(); // 清空FileWriter缓冲区
         fw.close();
     } catch (IOException e) {
         e.printStackTrace();
     }
     String complete = String.valueOf(researchId);
     // 复制空白文档-粘贴到临时文档(相当于手动执行copy_paste)
     MSOfficeGeneratorUtils officeUtils = new MSOfficeGeneratorUtils(false);
     officeUtils.openDocument(localpath + File.separator + "blank.doc");
     officeUtils.copy(); // 拷贝整篇文档
     officeUtils.close();
     officeUtils.createNewDocument();
     officeUtils.paste(); // 粘贴整篇文档
     // 将图片${image_name}替换为真实图片
     for (Entry<String, String> entry : imgMap.entrySet())
         officeUtils.replaceText2Image(entry.getKey(), entry.getValue());
     
     officeUtils.setFont(true, false, false, "0,0,0", "20", "宋体"); // 设置字体,具体参数
     officeUtils.saveAs(localpath + File.separator + complete + ".doc"); // 可生成UUID.doc文件,利用UUID防止同名
     officeUtils.close(); // 关闭Office Word创建的文档
     officeUtils.quit(); // 退出Office Word程序
     imgMap.clear();
     return complete;
 }
 
/**
 *  替换img标签为p标签
 * 
 * @param node 
 * @param imgPath 本地图片存储路径
 * @param imgMap key:${imgName} value:
 */
public static void sysElementText(Node node, String imgPath, Map<String, String> imgMap) {
  	if (node.childNodes().size() == 0) {
  		if (node.nodeName().equals("img")) {
  			String src = node.attr("src");
			String fileName = src.substring(src.lastIndexOf("/") + 1, src.length());
			Element element = new Element("p");
			element.append("${"+fileName+"}");
			element.attr("style", node.attr("style"));
			node.replaceWith(element);
			imgMap.put("${"+fileName+"}", imgPath + File.separator + fileName);
  		}
  	}
  	if (node.childNodes().size() > 0) {
  		List<Node> childNodes = node.childNodes();
  		for (Node node2 : childNodes) {
  			if (node2.nodeName().equals("img")) {
  				String src = node2.attr("src");
  				String fileName = src.substring(src.lastIndexOf("/") + 1, src.length());
  				Element element = new Element("p");
  				element.append("${"+fileName+"}");
  				element.attr("style", node2.attr("style"));
  				node2.replaceWith(element);
  				imgMap.put("${"+fileName+"}", imgPath + File.separator + fileName);
  			}
		}
  	}
}

    /**
     * 创建word文档
     * 
     * @param localpath
     * @param name
     * @return
     */
    public static void createWord(String localpath, String name) {
        MSOfficeGeneratorUtils msOfficeUtils = new MSOfficeGeneratorUtils(false); // 整合过程设置为可见
        msOfficeUtils.createNewDocument();
        msOfficeUtils.saveAs(localpath + File.separator + name + ".doc");
        msOfficeUtils.close();
        msOfficeUtils.quit();
    }

MSOfficeGeneratorUtils该类参考:http://www.cnblogs.com/liudaihuablogs/p/9761297.html

2.3 思考

该方式转换图片正常显示,唯一不足的地方在于jacob使用的是office的api,服务器必须是windows,在linux下是不能运行的,所以很奔溃。
于是,我们申请一台windows服务器,在该调用HTML转word前,发送消息给windows服务器执行生成word。之后,通过Smb服务,java中的SmbFile获取远程文件到本地。

3. 使用itext进行转化

依赖jar
itext-2.1.7.jar
itext-rtf-2.1.7.jar

3.1 思路

a). 将img标签中的src修改为本地图片路径
b). 以rtf方式导出为word

3.2 代码示例

private static void html2WordIText(String html, String noteName, String reportDirName, long researchId) {
	// 图片临时存放路径
	String pwd = "tmp/researchNote";
	Set<String> srcSet = ImageUtils.getImgStr(html);
	for (String src : srcSet) {
		String srcName = src.split("[/]")[src.split("[/]").length - 1];
		ImageUtils.download(src, srcName, pwd + "/" + String.valueOf(researchId));
		String newSrc = pwd + "/" + String.valueOf(researchId) + "/" + srcName;
		html = html.replace(src, newSrc);
	}
	FileUtils.fileIsExist(reportDirName);
	OutputStream out = null;
	try {
		out = new FileOutputStream(reportDirName + noteName);
		Document document = new Document(PageSize.A4);
		RtfWriter2.getInstance(document, out);
		document.open();
		Paragraph context = new Paragraph();
		// Image img = Image.getInstance("D:\\图片\\2.jpg");
		// img.setAbsolutePosition(0, 0);//
		// document.add(img);
		StyleSheet ss = new StyleSheet();
		HashMap<String, String> interfaceProps = Maps.newHashMap();
		interfaceProps.put("img_baseurl", "");
		List htmlList = HTMLWorker.parseToList(new StringReader(html), ss, interfaceProps);
		for (int i = 0; i < htmlList.size(); i++) {
			com.lowagie.text.Element e = (com.lowagie.text.Element) htmlList.get(i);
			context.add(e);
		}
		document.add(context);
		document.close();
		FileUtils.deletefile(pwd);
	} catch (Exception e) {
		
	} finally {
		try {
			if (out != null) {
				out.close();
			}
		} catch (IOException e) {
			
		}
	}
}

ImageUtils.java :
public static Set<String> getImgStr(String htmlStr) {
       Set<String> pics = new HashSet<String>();
       String img = "";
       Pattern pImage;
       Matcher mImage;
       String regEx_img = "<img.*src\\s*=\\s*(.*?)[^>]*?>";
       pImage = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE);
       mImage = pImage.matcher(htmlStr);
       while (mImage.find()) {
           // 得到<img />数据
           img = mImage.group();
           // 匹配<img>中的src数据 
           Matcher m = Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)").matcher(img);
           while (m.find()) {
               pics.add(m.group(1));
           }
       }
       return pics;
   }

 /**
	 * 下载图片
	 * @param urlString  路径
	 * @param filename   保存的文件名
	 * @param savePath   保存路径
	 */
	public static void download(String urlString, String filename, String savePath) {
	    InputStream is = null;
	    OutputStream os = null;
	    try {
	    	File researchFile = new File(savePath + File.separator + filename);
	    	if (researchFile.exists()) {
	    		return;
	    	}
	    	 // 构造URL
	        URL url = new URL(urlString);
	        // 打开连接
	        URLConnection con = url.openConnection(new Proxy();
	        // 设置请求超时为5s
	        con.setConnectTimeout(5*1000);
	        con.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); 
	        // 输入流
	        is = con.getInputStream();
	
	        // 1K的数据缓冲
	        byte[] bs = new byte[1024 * 1024 * 3];
	        // 读取到的数据长度
	        int len;
	        // 输出的文件流
	        File sf=new File(savePath);
	        if(!sf.exists()){
	            sf.mkdirs();
	        }
	        os = new FileOutputStream(sf.getPath() + File.separator + filename);
	        // 开始读取
	        while ((len = is.read(bs)) != -1) {
	            os.write(bs, 0, len);
	        }
	        // 完毕,关闭所有链接
	        os.close();
	        is.close();
	    } catch (IOException e) {
	        e.printStackTrace();
	    } finally {
	    	if (os != null) {
	    		try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
	    	}
	    }
	}

4. 总结

方法一断网无法显示图片,方法二linux下无法生成,方法三图片大小不易调整;但总体来说方法三优于前两者。如有错误还请指正,谢谢。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/182704.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Java NIO详解[通俗易懂]

    Java NIO详解[通俗易懂]JAVANIO简介NIO与IO的对比

    2022年7月8日
    18
  • JAVA设计模式之抽象工厂模式

    本文属于23种设计模式系列。继续前面简单工厂模式和工厂方法模式的例子,以汽车配件制造介绍抽象工厂模式。

    2022年3月11日
    40
  • xp 架设网站服务器软件,xp架设ftp服务器软件

    xp 架设网站服务器软件,xp架设ftp服务器软件xp架设ftp服务器软件内容精选换一换由于智能写Cache是华为自研闭源工具,仅支持华为鲲鹏处理器使用。需在所有云服务器上安装DataProvider软件,SAP技术支持人员通过该软件收集云服务器所在的平台信息,以便在SAP系统故障、性能下降时进行定位和分析。SAPNetWeaver所在的服务器上,在创建服务器的时候需要为其指定名为DataproviderAccess的Agency,同时也需…

    2022年7月21日
    12
  • Unity3d场景快速烘焙【2020】

    Unity3d场景快速烘焙【2020】很多刚刚接触Unity3d的童鞋花了大量的时间自学,可总是把握不好Unity3d的烘焙,刚从一个坑里爬出来,又陷入另一个新的坑,每次烘焙一个场景少则几个小时,多则几十个小时,机器总是处于假死机状态,半天看不到结果,好不容易烘焙完了,黑斑、撕裂、硬边、漏光或漏阴影等缺陷遍布,惨不忍睹,整体效果暗无层次,或者苍白无力,灯光该亮的亮不起来,该暗的暗不下去,更谈不上有什么意境,痛苦的折磨,近乎失去了信心,一个团队从建模到程序,都没什么问题,可一到烘焙这一关,就堵得心塞,怎么也搞不出好的视觉效果,作品没法及时向用户交

    2022年6月11日
    29
  • java treeNode 树转list

    java treeNode 树转list树转 list 一般转换方式递归 写起来复制 容易出错 这样就可以应用栈的进出规则进行转化 栈先进后出 https baike baidu com item E6 A0 88 fr aladdin publicList TreeNode node2List TreeNodenode 返回结果集 List TreeNode result TreeNode TreeNode

    2025年9月23日
    4
  • poe交换机和接入交换机的区别_光纤交换机和普通交换机的区别

    poe交换机和接入交换机的区别_光纤交换机和普通交换机的区别POE交换机与普通交换机区别的话,POE交换机就是除了能提供普通交换机所具有的传输功能,还能给网线的另一端设备提供供电功能。普通的交换机主要是交换数据的功能,并没有具备供电的功能。接下来我们就一起来详细看看POE交换机和普通交换机的区别具体有哪些?POE交换机和普通交换机具有以下几点区别:1.可靠性不同:POE交换机就是支持对网线供电的交换机,和普通交换机相比就是受电终端(比如AP、数字摄像头等)不用再进行电源布线,对整个网络而言可靠性更高。2.功能不同:POE交换机就是除了能提供普通交换机所

    2022年10月5日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号