整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

神奇的Python脚本pdf转word、doc转docx、word转html各种格式都有

迎点击右上角关注小编,除了分享技术文章之外还有很多福利,私信学习资料可以领取包括不限于Python实战演练、PDF电子文档、面试集锦、学习资料等。

前言

对于PDF转换成word文档,我想很多人都了解过,那就是需要付费,而且很贵,但是如果你会Python,只要你会Python这么问题都不再是问题。

pdf文件转换为word文件

Word文件转换为pdf文件

doc转docx

docx转html

.什么是tika?

Tika是一个内容分析工具,自带全面的parser工具类,能解析基本所有常见格式的文件,得到文件的metadata,content等内容,返回格式化信息。总的来说可以作为一个通用的解析工具。特别对于搜索引擎的数据抓去和处理步骤有重要意义。Tika是Apache的Lucene项目下面的子项目,在lucene的应用中可以使用tika获取大批量文档中的内容来建立索引,非常方便,也很容易使用。Apache Tika toolkit可以自动检测各种文档(如word,ppt,xml,csv,ppt等)的类型并抽取文档的元数据和文本内容。Tika集成了现有的文档解析库,并提供统一的接口,使针对不同类型的文档进行解析变得更简单。Tika针对搜索引擎索引、内容分析、转化等非常有用。

Tika架构

应用程序员可以很容易地在他们的应用程序集成Tika。Tika提供了一个命令行界面和图形用户界面,使它比较人性化。在本章中,我们将讨论构成Tika架构的四个重要模块。下图显示了Tika的四个模块的体系结构:

  • 语言检测机制。
  • MIME检测机制。
  • Parser接口。
  • Tika Facade 类.

语言检测机制

每当一个文本文件被传递到Tika,它将检测在其中的语言。它接受没有语言的注释文件和通过检测该语言添加在该文件的元数据信息。支持语言识别,Tika 有一类叫做语言标识符在包org.apache.tika.language及语言识别资料库里面包含了语言检测从给定文本的算法。Tika 内部使用N-gram算法语言检测。

MIME检测机制

Tika可以根据MIME标准检测文档类型。Tika默认MIME类型检测是使用org.apache.tika.mime.mimeTypes。它使用org.apache.tika.detect.Detector 接口大部分内容类型检测。内部Tika使用多种技术,如文件匹配替换,内容类型提示,魔术字节,字符编码,以及其他一些技术。

解析器接口

org.apache.tika.parser 解析器接口是Tika解析文档的主要接口。该接口从提取文档中的文本和元数据,并总结了其对外部用户愿意写解析器插件。采用不同的具体解析器类,具体为各个文档类型,Tika 支持大量的文件格式。这些格式的具体类不同的文件格式提供支持,无论是通过直接实现逻辑分析器或使用外部解析器库。

Tika Facade 类

使用的Tika facade类是从Java调用Tika的最简单和直接的方式,而且也沿用了外观的设计模式。可以在 Tika API的org.apache.tika包Tika 找到外观facade类。通过实现基本用例,Tika作为facade的代理。它抽象了的Tika库的底层复杂性,例如MIME检测机制,解析器接口和语言检测机制,并提供给用户一个简单的接口来使用。

2.代码工程

实验目标

实现word文档转html

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot-demo</artifactId>
        <groupId>com.et</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>tika</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tika</groupId>
            <artifactId>tika-parsers</artifactId>
            <version>1.17</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

    </dependencies>
</project>

controller

package com.et.tika.controller;

import com.et.tika.convertor.WordToHtmlConverter;
import com.et.tika.dto.ConvertedDocumentDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;

@RestController
@Slf4j
public class HelloWorldController {
    @RequestMapping("/hello")
    public Map<String, Object> showHelloWorld(){
        Map<String, Object> map = new HashMap<>();
        map.put("msg", "HelloWorld");
        return map;
    }
    @Autowired
    WordToHtmlConverter converter;



    /**
     * Transforms the Word document into HTML document and returns the transformed document.
     *
     * @return  The content of the uploaded document as HTML.
     */
    @RequestMapping(value = "/api/word-to-html", method = RequestMethod.POST)
    public ConvertedDocumentDTO convertWordDocumentIntoHtmlDocument(@RequestParam(value = "file", required = true) MultipartFile wordDocument) {
        log.info("Converting word document into HTML document");

        ConvertedDocumentDTO htmlDocument = converter.convertWordDocumentIntoHtml(wordDocument);

        log.info("Converted word document into HTML document.");
        log.trace("The created HTML markup looks as follows: {}", htmlDocument);

        return htmlDocument;
    }
}

WordToHtmlConverter

package com.et.tika.convertor;


import com.et.tika.dto.ConvertedDocumentDTO;
import com.et.tika.exception.DocumentConversionException;
import lombok.extern.slf4j.Slf4j;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.parser.microsoft.ooxml.OOXMLParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.xml.sax.SAXException;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.TransformerException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;

/**
 *
 */
@Component
@Slf4j
public class WordToHtmlConverter {


    /**
     * Converts a .docx document into HTML markup. This code
     * is based on <a href="http://stackoverflow.com/a/9053258/313554">this StackOverflow</a> answer.
     *
     * @param wordDocument  The converted .docx document.
     * @return
     */
    public ConvertedDocumentDTO convertWordDocumentIntoHtml(MultipartFile wordDocument) {
        log.info("Converting word document: {} into HTML", wordDocument.getOriginalFilename());
        try {
            InputStream input = wordDocument.getInputStream();
            Parser parser = new OOXMLParser();

            StringWriter sw = new StringWriter();
            SAXTransformerFactory factory = (SAXTransformerFactory)
                    SAXTransformerFactory.newInstance();
            TransformerHandler handler = factory.newTransformerHandler();
            handler.getTransformer().setOutputProperty(OutputKeys.ENCODING, "utf-8");
            handler.getTransformer().setOutputProperty(OutputKeys.METHOD, "html");
            handler.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes");
            handler.setResult(new StreamResult(sw));

            Metadata metadata = new Metadata();
            metadata.add(Metadata.CONTENT_TYPE, "text/html;charset=utf-8");
            parser.parse(input, handler, metadata, new ParseContext());
            return new ConvertedDocumentDTO(wordDocument.getOriginalFilename(), sw.toString());
        }
        catch (IOException | SAXException | TransformerException | TikaException ex) {
            log.error("Conversion failed because an exception was thrown", ex);
            throw new DocumentConversionException(ex.getMessage(), ex);
        }
    }
}

dto

package com.et.tika.dto;

import org.apache.commons.lang.builder.ToStringBuilder;

/**
 *
 */
public  class ConvertedDocumentDTO {

    private final String contentAsHtml;
    private final String filename;

    public ConvertedDocumentDTO(String filename, String contentAsHtml) {
        this.contentAsHtml = contentAsHtml;
        this.filename = filename;
    }

    public String getContentAsHtml() {
        return contentAsHtml;
    }

    public String getFilename() {
        return filename;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this)
                .append("filename", this.filename)
                .append("contentAsHtml", this.contentAsHtml)
                .toString();
    }
}

自定义异常

package com.et.tika.exception;

/**
 *
 */
public final class DocumentConversionException extends RuntimeException {

    public DocumentConversionException(String message, Exception ex) {
        super(message, ex);
    }
}

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

  • https://github.com/Harries/springboot-demo

3.测试

启动Spring Boot应用

测试word转html

4.引用

  • https://tika.apache.org/
  • http://www.liuhaihua.cn/archives/710679.html

、前言

实现文档在线预览的方式除了上篇文章 文档在线预览新版(一)通过将文件转成图片实现在线预览功能说的将文档转成图片的实现方式外,还有转成pdf,前端通过pdf.js、pdfobject.js等插件来实现在线预览,以及本文将要说到的将文档转成html的方式来实现在线预览。

以下代码分别提供基于aspose、pdfbox、spire来实现来实现txt、word、pdf、ppt、word等文件转图片的需求。

1、aspose

Aspose 是一家致力于.Net ,Java,SharePoint,JasperReports和SSRS组件的提供商,数十个国家的数千机构都有用过aspose组件,创建、编辑、转换或渲染 Office、OpenOffice、PDF、图像、ZIP、CAD、XPS、EPS、PSD 和更多文件格式。注意aspose是商用组件,未经授权导出文件里面都是是水印(尊重版权,远离破解版)。

需要在项目的pom文件里添加如下依赖

        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>aspose-words</artifactId>
            <version>23.1</version>
        </dependency>
        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>aspose-pdf</artifactId>
            <version>23.1</version>
        </dependency>
        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>aspose-cells</artifactId>
            <version>23.1</version>
        </dependency>
        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>aspose-slides</artifactId>
            <version>23.1</version>
        </dependency>

2 、poi + pdfbox

因为aspose和spire虽然好用,但是都是是商用组件,所以这里也提供使用开源库操作的方式的方式。

POI是Apache软件基金会用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能。

Apache PDFBox是一个开源Java库,支持PDF文档的开发和转换。 使用此库,您可以开发用于创建,转换和操作PDF文档的Java程序。

需要在项目的pom文件里添加如下依赖

		<dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.4</version>
        </dependency>
		<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-excelant</artifactId>
            <version>5.2.0</version>
        </dependency>

3 spire

spire一款专业的Office编程组件,涵盖了对Word、Excel、PPT、PDF等文件的读写、编辑、查看功能。spire提供免费版本,但是存在只能导出前3页以及只能导出前500行的限制,只要达到其一就会触发限制。需要超出前3页以及只能导出前500行的限制的这需要购买付费版(尊重版权,远离破解版)。这里使用免费版进行演示。

spire在添加pom之前还得先添加maven仓库来源

		<repository>
            <id>com.e-iceblue</id>
            <name>e-iceblue</name>
            <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
        </repository>

接着在项目的pom文件里添加如下依赖

免费版:

		<dependency>
            <groupId>e-iceblue</groupId>
            <artifactId>spire.office.free</artifactId>
            <version>5.3.1</version>
        </dependency>

付费版版:

		<dependency>
            <groupId>e-iceblue</groupId>
            <artifactId>spire.office</artifactId>
            <version>5.3.1</version>
        </dependency>

二、将文件转换成html字符串

1、将word文件转成html字符串

1.1 使用aspose

public static String wordToHtmlStr(String wordPath) {
        try {
            Document doc = new Document(wordPath); // Address是将要被转化的word文档
            String htmlStr = doc.toString();
            return htmlStr;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

验证结果:

1.2 使用poi

public String wordToHtmlStr(String wordPath) throws TransformerException, IOException, ParserConfigurationException {
        String htmlStr = null;
        String ext = wordPath.substring(wordPath.lastIndexOf("."));
        if (ext.equals(".docx")) {
            htmlStr = word2007ToHtmlStr(wordPath);
        } else if (ext.equals(".doc")){
            htmlStr = word2003ToHtmlStr(wordPath);
        } else {
            throw new RuntimeException("文件格式不正确");
        }
        return htmlStr;
    }

    public String word2007ToHtmlStr(String wordPath) throws IOException {
        // 使用内存输出流
        try(ByteArrayOutputStream out = new ByteArrayOutputStream()){
            word2007ToHtmlOutputStream(wordPath, out);
            return out.toString();
        }
    }

    private void word2007ToHtmlOutputStream(String wordPath,OutputStream out) throws IOException {
        ZipSecureFile.setMinInflateRatio(-1.0d);
        InputStream in = Files.newInputStream(Paths.get(wordPath));
        XWPFDocument document = new XWPFDocument(in);
        XHTMLOptions options = XHTMLOptions.create().setIgnoreStylesIfUnused(false).setImageManager(new Base64EmbedImgManager());
        // 使用内存输出流
        XHTMLConverter.getInstance().convert(document, out, options);
    }


    private String word2003ToHtmlStr(String wordPath) throws TransformerException, IOException, ParserConfigurationException {
        org.w3c.dom.Document htmlDocument = word2003ToHtmlDocument(wordPath);
        // Transform document to string
        StringWriter writer = new StringWriter();
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
        transformer.setOutputProperty(OutputKeys.METHOD, "html");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.transform(new DOMSource(htmlDocument), new StreamResult(writer));
        return writer.toString();
    }

private org.w3c.dom.Document word2003ToHtmlDocument(String wordPath) throws IOException, ParserConfigurationException {
        InputStream input = Files.newInputStream(Paths.get(wordPath));
        HWPFDocument wordDocument = new HWPFDocument(input);
        WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
                DocumentBuilderFactory.newInstance().newDocumentBuilder()
                        .newDocument());
        wordToHtmlConverter.setPicturesManager((content, pictureType, suggestedName, widthInches, heightInches) -> {
            System.out.println(pictureType);
            if (PictureType.UNKNOWN.equals(pictureType)) {
                return null;
            }
            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);
        return wordToHtmlConverter.getDocument();
    }

1.3 使用spire

 public String wordToHtmlStr(String wordPath) throws IOException {
        try(ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            Document document = new Document();
            document.loadFromFile(wordPath);
            document.saveToFile(outputStream, FileFormat.Html);
            return outputStream.toString();
        }
    }

2、将pdf文件转成html字符串

2.1 使用aspose

public static String pdfToHtmlStr(String pdfPath) throws IOException, ParserConfigurationException {
        PDDocument document = PDDocument.load(new File(pdfPath));
        Writer writer = new StringWriter();
        new PDFDomTree().writeText(document, writer);
        writer.close();
        document.close();
        return writer.toString();
    }

验证结果:

2.2 使用 poi + pbfbox

public String pdfToHtmlStr(String pdfPath) throws IOException, ParserConfigurationException {
        PDDocument document = PDDocument.load(new File(pdfPath));
        Writer writer = new StringWriter();
        new PDFDomTree().writeText(document, writer);
        writer.close();
        document.close();
        return writer.toString();
    }

2.3 使用spire

public String pdfToHtmlStr(String pdfPath) throws IOException, ParserConfigurationException {
        try(ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            PdfDocument pdf = new PdfDocument();
            pdf.loadFromFile(pdfPath);
            return outputStream.toString();
        }
    }

3、将excel文件转成html字符串

3.1 使用aspose

public static String excelToHtmlStr(String excelPath) throws Exception {
        FileInputStream fileInputStream = new FileInputStream(excelPath);
        Workbook workbook = new XSSFWorkbook(fileInputStream);
        DataFormatter dataFormatter = new DataFormatter();
        FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
        Sheet sheet = workbook.getSheetAt(0);
        StringBuilder htmlStringBuilder = new StringBuilder();
        htmlStringBuilder.append("<html><head><title>Excel to HTML using Java and POI library</title>");
        htmlStringBuilder.append("<style>table, th, td { border: 1px solid black; }</style>");
        htmlStringBuilder.append("</head><body><table>");
        for (Row row : sheet) {
            htmlStringBuilder.append("<tr>");
            for (Cell cell : row) {
                CellType cellType = cell.getCellType();
                if (cellType == CellType.FORMULA) {
                    formulaEvaluator.evaluateFormulaCell(cell);
                    cellType = cell.getCachedFormulaResultType();
                }
                String cellValue = dataFormatter.formatCellValue(cell, formulaEvaluator);
                htmlStringBuilder.append("<td>").append(cellValue).append("</td>");
            }
            htmlStringBuilder.append("</tr>");
        }
        htmlStringBuilder.append("</table></body></html>");
        return htmlStringBuilder.toString();
    }

返回的html字符串:

<html><head><title>Excel to HTML using Java and POI library</title><style>table, th, td { border: 1px solid black; }</style></head><body><table><tr><td>序号</td><td>姓名</td><td>性别</td><td>联系方式</td><td>地址</td></tr><tr><td>1</td><td>张晓玲</td><td>女</td><td>11111111111</td><td>上海市浦东新区xx路xx弄xx号</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦东新区xx路xx弄xx号</td></tr><tr><td>1</td><td>张晓玲</td><td>女</td><td>11111111111</td><td>上海市浦东新区xx路xx弄xx号</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦东新区xx路xx弄xx号</td></tr><tr><td>1</td><td>张晓玲</td><td>女</td><td>11111111111</td><td>上海市浦东新区xx路xx弄xx号</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦东新区xx路xx弄xx号</td></tr><tr><td>1</td><td>张晓玲</td><td>女</td><td>11111111111</td><td>上海市浦东新区xx路xx弄xx号</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦东新区xx路xx弄xx号</td></tr><tr><td>1</td><td>张晓玲</td><td>女</td><td>11111111111</td><td>上海市浦东新区xx路xx弄xx号</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦东新区xx路xx弄xx号</td></tr><tr><td>1</td><td>张晓玲</td><td>女</td><td>11111111111</td><td>上海市浦东新区xx路xx弄xx号</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦东新区xx路xx弄xx号</td></tr><tr><td>1</td><td>张晓玲</td><td>女</td><td>11111111111</td><td>上海市浦东新区xx路xx弄xx号</td></tr><tr><td>2</td><td>王小二</td><td>男</td><td>1222222</td><td>上海市浦东新区xx路xx弄xx号</td></tr></table></body></html>

3.2 使用poi + pdfbox

public String excelToHtmlStr(String excelPath) throws Exception {
        FileInputStream fileInputStream = new FileInputStream(excelPath);
        try (Workbook workbook = WorkbookFactory.create(new File(excelPath))){
            DataFormatter dataFormatter = new DataFormatter();
            FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
            org.apache.poi.ss.usermodel.Sheet sheet = workbook.getSheetAt(0);
            StringBuilder htmlStringBuilder = new StringBuilder();
            htmlStringBuilder.append("<html><head><title>Excel to HTML using Java and POI library</title>");
            htmlStringBuilder.append("<style>table, th, td { border: 1px solid black; }</style>");
            htmlStringBuilder.append("</head><body><table>");
            for (Row row : sheet) {
                htmlStringBuilder.append("<tr>");
                for (Cell cell : row) {
                    CellType cellType = cell.getCellType();
                    if (cellType == CellType.FORMULA) {
                        formulaEvaluator.evaluateFormulaCell(cell);
                        cellType = cell.getCachedFormulaResultType();
                    }
                    String cellValue = dataFormatter.formatCellValue(cell, formulaEvaluator);
                    htmlStringBuilder.append("<td>").append(cellValue).append("</td>");
                }
                htmlStringBuilder.append("</tr>");
            }
            htmlStringBuilder.append("</table></body></html>");
            return htmlStringBuilder.toString();
        }
    }

3.3 使用spire

public String excelToHtmlStr(String excelPath) throws Exception {
        try(ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            Workbook workbook = new Workbook();
            workbook.loadFromFile(excelPath);
            workbook.saveToStream(outputStream, com.spire.xls.FileFormat.HTML);
            return outputStream.toString();
        }
    }

三、将文件转换成html,并生成html文件

有时我们是需要的不仅仅返回html字符串,而是需要生成一个html文件这时应该怎么做呢?一个改动量小的做法就是使用org.apache.commons.io包下的FileUtils工具类写入目标地址:

FileUtils类将html字符串生成html文件示例:

首先需要引入pom:

		<dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.8.0</version>
        </dependency>

相关代码:

String htmlStr = FileConvertUtil.pdfToHtmlStr("D:\\书籍\\电子书\\小说\\历史小说\\最后的可汗.doc");
FileUtils.write(new File("D:\\test\\doc.html"), htmlStr, "utf-8");

除此之外,还可以对上面的代码进行一些调整,已实现生成html文件,代码调整如下:

1、将word文件转换成html文件

word原文件效果:

1.1 使用aspose

public static void wordToHtml(String wordPath, String htmlPath) {
        try {
            File sourceFile = new File(wordPath);
            String path = htmlPath + File.separator + sourceFile.getName().substring(0, sourceFile.getName().lastIndexOf(".")) + ".html";
            File file = new File(path); // 新建一个空白pdf文档
            FileOutputStream os = new FileOutputStream(file);
            Document doc = new Document(wordPath); // Address是将要被转化的word文档
            HtmlSaveOptions options = new HtmlSaveOptions();
            options.setExportImagesAsBase64(true);
            options.setExportRelativeFontSize(true);
            doc.save(os, options);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

转换成html的效果:

1.2 使用poi + pdfbox

public void wordToHtml(String wordPath, String htmlPath) throws TransformerException, IOException, ParserConfigurationException {
        htmlPath = FileUtil.getNewFileFullPath(wordPath, htmlPath, "html");
        String ext = wordPath.substring(wordPath.lastIndexOf("."));
        if (ext.equals(".docx")) {
            word2007ToHtml(wordPath, htmlPath);
        } else if (ext.equals(".doc")){
            word2003ToHtml(wordPath, htmlPath);
        } else {
            throw new RuntimeException("文件格式不正确");
        }
    }

    public void word2007ToHtml(String wordPath, String htmlPath) throws TransformerException, IOException, ParserConfigurationException {
        //try(OutputStream out = Files.newOutputStream(Paths.get(path))){
        try(FileOutputStream out = new FileOutputStream(htmlPath)){
            word2007ToHtmlOutputStream(wordPath, out);
        }
    }

    private void word2007ToHtmlOutputStream(String wordPath,OutputStream out) throws IOException {
        ZipSecureFile.setMinInflateRatio(-1.0d);
        InputStream in = Files.newInputStream(Paths.get(wordPath));
        XWPFDocument document = new XWPFDocument(in);
        XHTMLOptions options = XHTMLOptions.create().setIgnoreStylesIfUnused(false).setImageManager(new Base64EmbedImgManager());
        // 使用内存输出流
        XHTMLConverter.getInstance().convert(document, out, options);
    }

    public void word2003ToHtml(String wordPath, String htmlPath) throws TransformerException, IOException, ParserConfigurationException {
        org.w3c.dom.Document htmlDocument = word2003ToHtmlDocument(wordPath);
        // 生成html文件地址

        try(OutputStream outStream = Files.newOutputStream(Paths.get(htmlPath))){
            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);
        }
    }

    private org.w3c.dom.Document word2003ToHtmlDocument(String wordPath) throws IOException, ParserConfigurationException {
        InputStream input = Files.newInputStream(Paths.get(wordPath));
        HWPFDocument wordDocument = new HWPFDocument(input);
        WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
                DocumentBuilderFactory.newInstance().newDocumentBuilder()
                        .newDocument());
        wordToHtmlConverter.setPicturesManager((content, pictureType, suggestedName, widthInches, heightInches) -> {
            System.out.println(pictureType);
            if (PictureType.UNKNOWN.equals(pictureType)) {
                return null;
            }
            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);
        return wordToHtmlConverter.getDocument();
    }

转换成html的效果:

1.3 使用spire

public void wordToHtml(String wordPath, String htmlPath) {
        htmlPath = FileUtil.getNewFileFullPath(wordPath, htmlPath, "html");
        Document document = new Document();
        document.loadFromFile(wordPath);
        document.saveToFile(htmlPath, FileFormat.Html);
    }

转换成html的效果:

因为使用的是免费版,存在页数和字数限制,需要完整功能的的可以选择付费版本。PS:这回76页的文档居然转成功了前50页。

2、将pdf文件转换成html文件

图片版pdf原文件效果:

文字版pdf原文件效果:

2.1 使用aspose

public static void pdfToHtml(String pdfPath, String htmlPath) throws IOException, ParserConfigurationException {
        File file = new File(pdfPath);
        String path = htmlPath + File.separator + file.getName().substring(0, file.getName().lastIndexOf(".")) + ".html";
        PDDocument document = PDDocument.load(new File(pdfPath));
        Writer writer = new PrintWriter(path, "UTF-8");
        new PDFDomTree().writeText(document, writer);
        writer.close();
        document.close();
    }

图片版PDF文件验证结果:

文字版PDF文件验证结果:

2.2 使用poi + pdfbox

public void pdfToHtml(String pdfPath, String htmlPath) throws IOException, ParserConfigurationException {
        String path = FileUtil.getNewFileFullPath(pdfPath, htmlPath, "html");
        PDDocument document = PDDocument.load(new File(pdfPath));
        Writer writer = new PrintWriter(path, "UTF-8");
        new PDFDomTree().writeText(document, writer);
        writer.close();
        document.close();
    }

图片版PDF文件验证结果:

文字版PDF原文件效果:

2.3 使用spire

public void pdfToHtml(String pdfPath, String htmlPath) throws IOException, ParserConfigurationException {
        htmlPath = FileUtil.getNewFileFullPath(pdfPath, htmlPath, "html");
        PdfDocument pdf = new PdfDocument();
        pdf.loadFromFile(pdfPath);
        pdf.saveToFile(htmlPath, com.spire.pdf.FileFormat.HTML);
    }

图片版PDF文件验证结果:
因为使用的是免费版,所以只有前三页是正常的。。。有超过三页需求的可以选择付费版本。

文字版PDF原文件效果:

报错了无法转换。。。

java.lang.NullPointerException
	at com.spire.pdf.PdfPageWidget.spr┢⅛(Unknown Source)
	at com.spire.pdf.PdfPageWidget.getSize(Unknown Source)
	at com.spire.pdf.PdfPageBase.spr†™—(Unknown Source)
	at com.spire.pdf.PdfPageBase.getActualSize(Unknown Source)
	at com.spire.pdf.PdfPageBase.getSection(Unknown Source)
	at com.spire.pdf.general.PdfDestination.spr︻┎—(Unknown Source)
	at com.spire.pdf.general.PdfDestination.spr┻┑—(Unknown Source)
	at com.spire.pdf.general.PdfDestination.getElement(Unknown Source)
	at com.spire.pdf.primitives.PdfDictionary.setProperty(Unknown Source)
	at com.spire.pdf.bookmarks.PdfBookmark.setDestination(Unknown Source)
	at com.spire.pdf.bookmarks.PdfBookmarkWidget.spr┭┘—(Unknown Source)
	at com.spire.pdf.bookmarks.PdfBookmarkWidget.getDestination(Unknown Source)
	at com.spire.pdf.PdfDocumentBase.spr╻⅝(Unknown Source)
	at com.spire.pdf.widget.PdfPageCollection.spr┦⅝(Unknown Source)
	at com.spire.pdf.widget.PdfPageCollection.removeAt(Unknown Source)
	at com.spire.pdf.PdfDocumentBase.spr┞⅝(Unknown Source)
	at com.spire.pdf.PdfDocument.loadFromFile(Unknown Source)

3、将excel文件转换成html文件

excel原文件效果:

3.1 使用aspose

public void excelToHtml(String excelPath, String htmlPath) throws Exception {
        htmlPath = FileUtil.getNewFileFullPath(excelPath, htmlPath, "html");
        Workbook workbook = new Workbook(excelPath);
        com.aspose.cells.HtmlSaveOptions options = new com.aspose.cells.HtmlSaveOptions();
        workbook.save(htmlPath, options);
    }

转换成html的效果:

3.2 使用poi

public void excelToHtml(String excelPath, String htmlPath) throws Exception {
        String path = FileUtil.getNewFileFullPath(excelPath, htmlPath, "html");
        try(FileOutputStream fileOutputStream = new FileOutputStream(path)){
            String htmlStr = excelToHtmlStr(excelPath);
            byte[] bytes = htmlStr.getBytes();
            fileOutputStream.write(bytes);
        }
    }


    public String excelToHtmlStr(String excelPath) throws Exception {
        FileInputStream fileInputStream = new FileInputStream(excelPath);
        try (Workbook workbook = WorkbookFactory.create(new File(excelPath))){
            DataFormatter dataFormatter = new DataFormatter();
            FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
            org.apache.poi.ss.usermodel.Sheet sheet = workbook.getSheetAt(0);
            StringBuilder htmlStringBuilder = new StringBuilder();
            htmlStringBuilder.append("<html><head><title>Excel to HTML using Java and POI library</title>");
            htmlStringBuilder.append("<style>table, th, td { border: 1px solid black; }</style>");
            htmlStringBuilder.append("</head><body><table>");
            for (Row row : sheet) {
                htmlStringBuilder.append("<tr>");
                for (Cell cell : row) {
                    CellType cellType = cell.getCellType();
                    if (cellType == CellType.FORMULA) {
                        formulaEvaluator.evaluateFormulaCell(cell);
                        cellType = cell.getCachedFormulaResultType();
                    }
                    String cellValue = dataFormatter.formatCellValue(cell, formulaEvaluator);
                    htmlStringBuilder.append("<td>").append(cellValue).append("</td>");
                }
                htmlStringBuilder.append("</tr>");
            }
            htmlStringBuilder.append("</table></body></html>");
            return htmlStringBuilder.toString();
        }
    }

转换成html的效果:

3.3 使用spire

public void excelToHtml(String excelPath, String htmlPath) throws Exception {
        htmlPath = FileUtil.getNewFileFullPath(excelPath, htmlPath, "html");
        Workbook workbook = new Workbook();
        workbook.loadFromFile(excelPath);
        workbook.saveToFile(htmlPath, com.spire.xls.FileFormat.HTML);
    }

转换成html的效果:

四、总结

从上述的效果展示我们可以发现其实转成html效果不是太理想,很多细节样式没有还原,这其实是因为这类转换往往都是追求目标是通过使用文档中的语义信息并忽略其他细节来生成简单干净的 HTML,所以在转换过程中复杂样式被忽略,比如居中、首行缩进、字体,文本大小,颜色。举个例子在转换是 会将应用标题 1 样式的任何段落转换为 h1 元素,而不是尝试完全复制标题的样式。所以转成html的显示效果往往和原文档不太一样。这意味着对于较复杂的文档而言,这种转换不太可能是完美的。但如果都是只使用简单样式文档或者对文档样式不太关心的这种方式也不妨一试。

PS:如果想要展示效果好的话,其实可以将上篇文章《文档在线预览(一)通过将txt、word、pdf转成图片实现在线预览功能》说的内容和本文结合起来使用,即将文档里的内容都生成成图片(很可能是多张图片),然后将生成的图片全都放到一个html页面里 ,用html+css来保持样式并实现多张图片展示,再将html返回。开源组件kkfilevie就是用的就是这种做法。

kkfileview展示效果如下:

下图是kkfileview返回的html代码,从html代码我们可以看到kkfileview其实是将文件(txt文件除外)每页的内容都转成了图片,然后将这些图片都嵌入到一个html里,再返回给用户一个html页面。