现有的需求是前端导入word文件,然后需要在浏览器上展示出来,实现方案是将前端导入的word转成html的形式,再输出给前端,废话不多说,直接上代码.
需要用到的依赖
org.apache.poi poi-scratchpad 4.1.2 org.apache.poi poi 4.1.2 org.apache.poi poi-ooxml 4.1.2 fr.opensagres.xdocreport fr.opensagres.poi.xwpf.converter.xhtml 2.0.2
代码实现
public static String word2007ToHtml(MultipartFile file) throws IOException {
String html = null;
if (file.isEmpty() || file.getSize() <= 0) {
log.error("Sorry File does not Exists!");
return null;
} else {
/* 判断是否为docx文件 */
if (Objects.requireNonNull(file.getOriginalFilename()).endsWith(".docx") || file.getOriginalFilename().endsWith(".DOCX")) {
// 1)加载word文档生成XWPFDocument对象
@Cleanup FileInputStream in = (FileInputStream) file.getInputStream();
XWPFDocument document = new XWPFDocument(in);
// 2)解析XHTML配置(这里设置IURIResolver来设置图片存放的目录)
XHTMLOptions options = XHTMLOptions.create();
//3.将word中图片保存到oss中
options.setImageManager(SpringUtil.getBean(ImageManagerImpl.class));
options.setIgnoreStylesIfUnused(false);
options.setFragment(true);
// 3)将XWPFDocument转换成XHTML
@Cleanup ByteArrayOutputStream baos = new ByteArrayOutputStream();
XHTMLConverter.getInstance().convert(document, baos, options);
html = new String(baos.toByteArray(), StandardCharsets.UTF_8);
System.out.println(html);
} else {
System.out.println("Enter only as MS Office 2007+ files");
throw new BizException("word文档必须以.docx结尾");
}
}
return html;
}
注意事项
1.这个方法只支持docx结尾的文档,doc文档大同小异,如果有需要可以尝试自己写一下
2.和图片上传有关的这个类ImageManagerImpl,我就不写出来了,涉及公司的一些东西,如果你要用,只需要写个类继承一下 ImageManager 这个类,然后重写一下它的方法,也就是写一下你图片上传逻辑之类的就行了,如:
private byte[] picture;
private String suffix;
private String fileName;
public ImageManagerImpl() {
super(new File(""), "");
}
@Override
public void extract(String imagePath, byte[] imageData){
this.fileName = imagePath.split("\\.")[0];
this.suffix = "." + imagePath.split("\\.")[1];
this.picture = imageData;
}
@SneakyThrows
@Override
public String resolve(String uri) {
@Cleanup InputStream inputStream = new ByteArrayInputStream(picture);
MultipartFile fileResult = new MockMultipartFile(ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);
return uploadFile(fileResult,UUID.randomUUID().toString().replaceAll("-", "")+suffix);
}
3.生成后的html这个时候不能直接给前端,因为直接给前端的话会在传输过程中格式发生一些诡异的变化,我这里处理的方法是将html给base64加密,然后让前端去解析,这样就没问题了.
4. 其实这里生成的html都是一行行的div标签,并没有头和体的标签,虽然也能展示,但有些特殊用法的时候就不太行了,如html转PDF的时候,这个时候要么在生成html的时候加上去,要么在转PDF的时候加上去
htmlStr = "\n" + "\n" + "\t"+htmlDecode+"\t\n" + "";
注意这里是最后将html里面的字体全部统一成一种了,为了后期转PDF方便
好了,暂时就这么多,后续有时间再补充