poi xlsx转换html,word文档转html格式在线预览,使用了phpoffice,pydocx,java POI各方案,最终用unoconv解决...

最近客户要做一个word,excel 文件在线预览功能,以下是实现此功能的全过程。

由于我们用的是PHP开发项目,最开始想到的是用PHPoffice里的phpword来进行转换,以下是关键代码。<?php

$phpWord = \PhpOffice\PhpWord\IOFactory::load('test.doc');

$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, "HTML");

$xmlWriter->save('test.html);

用这种方法转是可以转,但是转出来的html文件相对原文件,丢失了很多字,如果说样式和原文不一样还可以忍受,但是内容丢失,就不太好了,而且对DOC格式又无法处理,所以这种方法,我最终选择了放弃。

然后,我就想用python来解决这个问题,查到了python有个pydocx库可以处理word文档,于是我就安装了一下。pip install pydocx

这个库用起来也很简单,主要代码如下:from pydocx import PyDocX

html = PyDocX.to_html("test2.doc")

f = open("test.html", 'w', encoding="utf-8")

f.write(html)

f.close()

转换效果也还可以,除了表格样式和原文有点不一样以外,内容倒是没丢失,但是有一个问题,这个库是转换docx的,对doc转换不了,我们客户还上传挺多doc格式的文件的,于是我只好另外想办法。

查资料发现java有个poi库可以用来对word文件进行转换, Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。我想试一下,查资料半天,就开始写了,先Maven引入依赖:

org.apache.poi

poi

4.1.2

org.apache.poi

poi-ooxml

4.1.2

org.apache.poi

poi-scratchpad

4.1.2

fr.opensagres.xdocreport

fr.opensagres.poi.xwpf.converter.xhtml

2.0.2

cn.hutoolhutool-all5.4.3

以下是引用别人的可用代码:import cn.hutool.core.img.ImgUtil;

import fr.opensagres.poi.xwpf.converter.xhtml.Base64EmbedImgManager;

import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLConverter;

import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLOptions;

import org.apache.poi.hwpf.HWPFDocument;

import org.apache.poi.hwpf.converter.WordToHtmlConverter;

import org.apache.poi.openxml4j.util.ZipSecureFile;

import org.apache.poi.xwpf.usermodel.XWPFDocument;

import org.w3c.dom.Document;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

import javax.xml.transform.OutputKeys;

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerException;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.dom.DOMSource;

import javax.xml.transform.stream.StreamResult;

import java.awt.image.BufferedImage;

import java.io.*;

/**

* office转换工具测试

*

*/

public class OfficeConvertUtil {

/**

* 将word2003转换为html文件 2017-2-27

*

* @param wordPath word文件路径

* @param wordName word文件名称无后缀

* @param suffix word文件后缀

* @throws IOException

* @throws TransformerException

* @throws ParserConfigurationException

*/

public static String Word2003ToHtml(String wordPath, String wordName,

String suffix) throws IOException, TransformerException,

ParserConfigurationException {

String htmlPath = wordPath + File.separator + "html"

+ File.separator;

String htmlName = wordName + ".html";

final String imagePath = htmlPath + "image" + File.separator;

// 判断html文件是否存在,每次重新生成

File htmlFile = new File(htmlPath + htmlName);

// if (htmlFile.exists()) {

// return htmlFile.getAbsolutePath();

// }

// 原word文档

final String file = wordPath + File.separator + wordName + suffix;

InputStream input = new FileInputStream(new File(file));

HWPFDocument wordDocument = new HWPFDocument(input);

WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(

DocumentBuilderFactory.newInstance().newDocumentBuilder()

.newDocument());

wordToHtmlConverter.setPicturesManager((content, pictureType, suggestedName, widthInches, heightInches) -> {

BufferedImage bufferedImage = ImgUtil.toImage(content);

String base64Img = ImgUtil.toBase64(bufferedImage, pictureType.getExtension());

// 带图片的word,则将图片转为base64编码,保存在一个页面中

StringBuilder sb = (new StringBuilder(base64Img.length() + "data:;base64,".length()).append("data:;base64,").append(base64Img));

return sb.toString();

});

// 解析word文档

wordToHtmlConverter.processDocument(wordDocument);

Document htmlDocument = wordToHtmlConverter.getDocument();

// 生成html文件上级文件夹

File folder = new File(htmlPath);

if (!folder.exists()) {

folder.mkdirs();

}

// 生成html文件地址

OutputStream outStream = new FileOutputStream(htmlFile);

DOMSource domSource = new DOMSource(htmlDocument);

StreamResult streamResult = new StreamResult(outStream);

TransformerFactory factory = TransformerFactory.newInstance();

Transformer serializer = factory.newTransformer();

serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");

serializer.setOutputProperty(OutputKeys.INDENT, "yes");

serializer.setOutputProperty(OutputKeys.METHOD, "html");

serializer.transform(domSource, streamResult);

outStream.close();

return htmlFile.getAbsolutePath();

}

/**

* 2007版本word转换成html 2017-2-27

*

* @param wordPath word文件路径

* @param wordName word文件名称无后缀

* @param suffix word文件后缀

* @return

* @throws IOException

*/

public static String Word2007ToHtml(String wordPath, String wordName, String suffix)

throws IOException {

ZipSecureFile.setMinInflateRatio(-1.0d);

String htmlPath = wordPath + File.separator + "html"

+ File.separator;

String htmlName = wordName + ".html";

String imagePath = htmlPath + "image" + File.separator;

// 判断html文件是否存在

File htmlFile = new File(htmlPath + htmlName);

// if (htmlFile.exists()) {

// return htmlFile.getAbsolutePath();

// }

// word文件

File wordFile = new File(wordPath + File.separator + wordName + suffix);

// 1) 加载word文档生成 XWPFDocument对象

InputStream in = new FileInputStream(wordFile);

XWPFDocument document = new XWPFDocument(in);

// 2) 解析 XHTML配置 (这里设置IURIResolver来设置图片存放的目录)

File imgFolder = new File(imagePath);

// 带图片的word,则将图片转为base64编码,保存在一个页面中

XHTMLOptions options = XHTMLOptions.create().indent(4).setImageManager(new Base64EmbedImgManager());

// 3) 将 XWPFDocument转换成XHTML

// 生成html文件上级文件夹

File folder = new File(htmlPath);

if (!folder.exists()) {

folder.mkdirs();

}

OutputStream out = new FileOutputStream(htmlFile);

XHTMLConverter.getInstance().convert(document, out, options);

return htmlFile.getAbsolutePath();

}

public static void main(String[] args) throws Exception {

System.out.println(Word2003ToHtml("D:\\tmp", "test", ".doc"));

System.out.println(Word2007ToHtml("D:\\tmp", "test2", ".docx"));

}

}

用java 倒是转换doc格式转的挺好的,但是转换docx格式的时候,样式全乱了,我查了半天POI的文档,网上也没有哪位大佬来解决这个样式乱的问题,于是我想用python来转docx ,java来转doc,但是又觉得太麻烦。

在查了半天资料以后,我最终的解决办法如下。

还是回到了用php处理,但是不是用phpoffice来处理,而是用unocov进行转换,先装libreofficeyum install libreoffice

然后装unocovyum install unoconv

用以下命令就可以转换了unoconv -f html -o test.html test.doc

-f是输出格式,-o是输出文件 最后面是输入文件,具体用法可以查相关文档,我在php里执行外部命令,生成转换好的文件以后再重定向到生成的文件上面去,由于excel 转html报错,所以我针对excel 转成了pdf.if (file_exists($source)) {

$dir = dirname($source);

$ext=pathinfo($source)['extension'];

if(!in_array($ext,['xls','xlsx'])){

$filetype='html';

}else $filetype='pdf';

$filename = strstr(basename($source), '.', true) . '.'.$filetype;

$file = $filename;

if(!file_exists('data/' . $file)){

//echo "sudo /usr/bin/unoconv -f {$filetype} -o " . '/data/web/public/data/' . $file . ' ' . '/data/web/data_manage/public/' . $source;exit;

$res= shell_exec("sudo /usr/bin/unoconv -f {$filetype} -o " . '/data/web/public/data/' . $file . ' ' . '/data/web/data_manage/public/' . $source);

if(!file_exists('data/' . $file)){

dump($res);

exit('生成预览文件出错');

}

}

header("Location:".'/data/' . $file);

exit();

} else exit('文件不存在');

最后,总算是把doc,docx 还有excel文件,wps文件都能预览出来,样式还是有点变化,内容没有丢失,客户也还算是能接受,以上是我解决这个问题的心得,希望能帮到大家。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值