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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux一些常用命令_运行命令

    linux一些常用命令_运行命令Linux常用命令大全第一章Linux基础命令【1】linux-》ls【2】linux-》alias【3】linux-》cd【4】linux-》clear【5】linux-》date【6】linux-》dpkg【7】linux-》echo【8】linux-》man手册【9】linux-》pwd【10】linux-》sort【11】linux-》uniq【12】linux-》which【13】linux-》管道|第二章Linux文件管理命令【14】linux-》cat

    2022年9月16日
    1
  • batchnorm原理及代码详解(笔记2)

    batchnorm原理及代码详解(笔记2)Batchnorm原理详解前言:Batchnorm是深度网络中经常用到的加速神经网络训练,加速收敛速度及稳定性的算法,可以说是目前深度网络必不可少的一部分。本文旨在用通俗易懂的语言,对深度学习的常用算法–batchnorm的原理及其代码实现做一个详细的解读。本文主要包括以下几个部分。Batchnorm主要解决的问题 Batchnorm原理解读 Batchnorm的优点 Batc…

    2022年5月28日
    33
  • ASSERT_VALID宏[通俗易懂]

    ASSERT_VALID宏[通俗易懂]ASSERT_VALID()验证指针是否指向空值//AssurethatpMyObjectisavalidpointertoan//objectderivedfromCObject.ASSERT_VALID(pMyObject);SeeAlso   ASSERT,VERIFY

    2022年9月5日
    2
  • BitBlt参数详解[通俗易懂]

    BitBlt参数详解[通俗易懂]对BitBlt()这个函数的最后一个参数的意义一直不是太了解,只会使用SRCCOPY,最近的一个项目使用到了这个函数,但是要求要背景透明的将源绘制到目标区域上,源是背景色和字,怎么只拷贝字而把背景色透明化呢??我的解决方法是,把源的背景色绘制为白色,字为黑色,然后在BitBlt的时候最后一个参数用SRCAND,果然可以达到我要的效果,这是为什么呢?呵呵趁此机会好好看看这个参数介绍吧~~开始之前,首先要明白,绘制其实就是在给每一个像素点涂颜色,每种颜色都是由红蓝黄三要素组合而成,因此通过RGB颜色值可以

    2022年10月18日
    0
  • 教育邮箱申请pycharm_python注册用户名和密码登录

    教育邮箱申请pycharm_python注册用户名和密码登录学生注册教育邮箱的方法不知道如何注册教育邮箱的看我上篇文。注册之后都会给登录的网址和初始密码。接下来进入这个网址JetBrains学生注册点击learnmore后,一直下拉点击applynow他会有一个信息表的填写进行申请后会发两个邮件,如下图,点击联接进行操作即可,网上说这个申请比较慢,我觉得还可以,可能是因为早上的关系,出现这个界面就说明注册成功了直接安装好pycharm的专业版在登录的时候直接填写我们的账号和密码就成功了,会显示使用终止…

    2022年8月28日
    0
  • JAVA设计模式之门面模式(外观模式)[通俗易懂]

    医院的例子  现代的软件系统都是比较复杂的,设计师处理复杂系统的一个常见方法便是将其“分而治之”,把一个系统划分为几个较小的子系统。如果把医院作为一个子系统,按照部门职能,这个系统可以划分为挂号、门诊、划价、化验、收费、取药等。看病的病人要与这些部门打交道,就如同一个子系统的客户端与一个子系统的各个类打交道一样,不是一件容易的事情。  首先病人必须先挂号,然后门诊。如果医生要求化验,病人必

    2022年3月11日
    46

发表回复

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

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