• 需求是:上传文件是word,介绍歌曲的,展示到歌曲详情页。不能是PDF链接跳转
  1. 首先实现的是word转pdf实现在线浏览文档。但是这样就得进入了歌曲详情页后点击链接跳转,不能一进去就加载出来。
  2. 继续,之后就在网上搜,怎么解决。发现可以集成富文本编辑器。不过,让我看到一篇文章poi 3.17 word 转 html(带图片格式),既然转成了html那么就直接引用就行了,还用啥富文本了。我也发现在word里面可以把docx转成htm,但是有个问题,上传到服务器之后图片没法显示。
  3. 直接拿上面那篇文章改就成了,它把图片解析出来放到了另外一个目录下,我用springboot去映射进行了

修改后代码

package com.folk.song.untils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import com.folk.song.domain.File1;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;


import fr.opensagres.poi.xwpf.converter.core.BasicURIResolver;
import fr.opensagres.poi.xwpf.converter.core.FileImageExtractor;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLConverter;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLOptions;

public class DocxToHtml {


    /**
     * docx to html
     *
     * @param in 输入流
     * @return
     * @throws IOException
     */
    public static InputStream docxToHtml(InputStream in, String filePath) {
        XWPFDocument document = null;
        try {
            document = new XWPFDocument(in);
            XHTMLOptions options = XHTMLOptions.create();
            //主要是这里,我百度不到这个类的api
            options.setIgnoreStylesIfUnused(false);
            options.setFragment(true);
            filePath = filePath+"wordImage/"+File.separator;
            options.setExtractor(new FileImageExtractor(new File(filePath)));
            options.URIResolver(new BasicURIResolver("http://47.93.2.237:8080/wordImages"));
            //这里是解析后html的img标签中src内容的前部分,后面的我不知道在哪里修改。
            //word/media/image1.jpeg后面会加这些。
            //当有多张图片 image2,image3这样名字不会冲突
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            XHTMLConverter.getInstance().convert(document, out, options);
            return new ByteArrayInputStream(out.toByteArray());
        } catch (IOException e) {
            System.out.println(e);
        }
        return in;
    }
	//我直接把html转成String输出了,没保存到本地
    public static String inputStreamToFile(InputStream inputStream) {
        ByteArrayOutputStream bos = null;
        try {
             bos = new ByteArrayOutputStream();//这个类可以把inputStream转为String
            int byteCount = 0;
            byte[] bytes = new byte[1024];
            while ((byteCount = inputStream.read(bytes)) != -1) {
                bos.write(bytes, 0, byteCount);//写入输出流
            }
            return bos.toString("UTF-8");//指定下编码,要不然会乱码
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
        return null;
    }

    public static String docxToHtml(File1 file1) {

        String s = null;
        try {
        	//服务器是centos,File1的存储看下面的图
            String filePathAndName = file1.getAddress()+file1.getUuidName();
            InputStream in = new FileInputStream(filePathAndName);// 读取文件的数据。
            InputStream result = docxToHtml(in,file1.getAddress());
            s = inputStreamToFile(result);
            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return s;
    }
}

spring boot word转换图片 springboot word转html_html


在springboot拦截器里面配置

spring boot word转换图片 springboot word转html_spring boot_02


访问浏览器前面地址会映射到服务器本地目录

maven依赖

<!--wordTohtml-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.17</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>

        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>xdocreport</artifactId>
            <version>2.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>3.17</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>ooxml-schemas</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.7</version>
        </dependency>

这里其实还有个问题,就是上传多个文档,每个文档都会把图片解析到同一个目录下面,就会覆盖掉之前解析的图片。我XHTMLOptions 这个类不了解,csdn也搜不到具体,只能搜到的和我代码一样的。解决也倒是解决了,每次请求都转一次word,也就解析一次图片,这样就不会有图片覆盖问题了。只是感觉解决的好拉跨。。。


遇到一个问题
其它word转html没问题,唯独有一个再删除四五次,重复加载之后报出来空指针异常,很是莫名其妙。一查发现

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

是这行代码有问题,咋也不知道为什么,用的是poi的代码。。。
去搜了一下,说是在这行代码前面加上document.createNumbering(); 我加上去了,问题解决了