SpringBoot整合openoffice實現word文檔的讀取和導入及報錯處理


 

先安裝openoffice4

Linux系統安裝參考:https://www.cnblogs.com/pxblog/p/11622969.html

Windows系統安裝參考:https://www.cnblogs.com/pxblog/p/14346148.html

 

引入jar包

https://yvioo.lanzous.com/b00o97q6d
密碼:1cjp

 

如果是pom文件的話

<dependency>
            <groupId>local</groupId>
            <artifactId>jodconverter</artifactId>
            <version>2.2.2</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/jodconverter-2.2.2.jar
            </systemPath>
        </dependency>
        <dependency>
            <groupId>local</groupId>
            <artifactId>jodconverter-cli</artifactId>
            <version>2.2.2</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/jodconverter-cli-2.2.2.jar
            </systemPath>
        </dependency>
        <dependency>
            <groupId>local</groupId>
            <artifactId>jodconverter-core</artifactId>
            <version>3.0-beta-4</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/jodconverter-core-3.0-beta-4.jar
            </systemPath>
        </dependency>

然后把jar包放到項目/webapp/WEB-INF/lib/下,這位置可以根據自己的來,然后pom文件路徑也做相應修改即可

 

日志注解用到了

<!--lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency> 

 

 

 

application.yml

spring:
  main:
    allow-bean-definition-overriding: true
  servlet:
    multipart:
      enabled: true #是否處理上傳
      max-file-size: 50MB #允許最大的單個上傳大小,單位可以是kb
      max-request-size: 50MB #允許最大請求大小

#文件上傳目錄
fileUploadPath: E://test//

openoffice:
  officeHome: D:\openoffice4  #openoffice的安裝路徑
  officePort: 8002   #openoffice啟動端口

 

 

UploadUtils.java

import org.apache.commons.lang.RandomStringUtils;


public class UploadUtils {


    /**
     * 36個小寫字母和數字
     */
    public static final char[] N36_CHARS = { '0', '1', '2', '3', '4', '5', '6',
            '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
            'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
            'x', 'y', 'z' };


    public static String generateFilename(String path, String ext) {
        return path + RandomStringUtils.random(8, N36_CHARS) + "." + ext;
    }




}

 

 

 

啟動類

OpenOfficeConverter.java

import com.test.UploadUtils;
import lombok.extern.slf4j.Slf4j;
import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileNotFoundException;


@Component
@Slf4j
public class OpenOfficeConverter {


    @Value("${openoffice.officeHome}")
    public String officeHome;

    @Value("${openoffice.officePort}")
    public Integer officePort;


    public void startService() {
        DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
        try {
            log.info("准備啟動服務....");
            //設置OpenOffice.org安裝目錄
            configuration.setOfficeHome(getOfficeHome());
            //設置轉換端口,默認為8100
            configuration.setPortNumber(getPort());
            //設置任務執行超時為5分鍾
            configuration.setTaskExecutionTimeout(1000 * 60 * 5L);
            //設置任務隊列超時為24小時
            configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);

            officeManager = configuration.buildOfficeManager();
            //啟動服務
            officeManager.start();
            log.info("office轉換服務啟動成功!");
        } catch (Exception ce) {
            log.error("office轉換服務啟動失敗!詳細信息:" + ce);
        }
    }

    public void stopService() {
        log.info("關閉office轉換服務....");
        if (officeManager != null) {
            officeManager.stop();
        }
        log.info("關閉office轉換成功!");
    }


    /**
     * 轉換格式
     *
     * @param inputFile 需要轉換的原文件路徑
     * @param fileType  要轉換的目標文件類型 html,pdf
     */
    public File convert(String inputFile, String fileType) {
        String outputFile = UploadUtils.generateFilename(getFilePath(), fileType);
        if (inputFile.endsWith(".txt")) {
            String odtFile = FileUtils.getFilePrefix(inputFile) + ".odt";
            if (new File(odtFile).exists()) {
                log.error("odt文件已存在!");
                inputFile = odtFile;
            } else {
                try {
                    FileUtils.copyFile(inputFile, odtFile);
                    inputFile = odtFile;
                } catch (FileNotFoundException e) {
                    log.error("文檔不存在!");
                    e.printStackTrace();
                }
            }
        }
        OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
        File output = new File(outputFile);
        converter.convert(new File(inputFile), output);
        return output;
    }


    public void init() {
        OpenOfficeConverter coverter = new OpenOfficeConverter(officeHome, officePort);
        coverter.startService();
        this.openOfficeConverter = coverter;
    }

    public void destroy() {
        this.openOfficeConverter.stopService();
    }


    @Autowired
    private OpenOfficeConverter openOfficeConverter;
    private static OfficeManager officeManager;
    public static final String HTML = "html";
    public static final String PDF = "pdf";
    public static final String TXT = "txt";
    public static final String DOC = "doc";
    public static final String DOCX = "docx";
    public static final String XLS = "xls";
    public static final String XLSX = "xlsx";
    public static final String PPT = "ppt";
    public static final String PPTX = "pptx";
    public static final String WPS = "wps";
    private int port = 8100;
    private String filePath;


    public OpenOfficeConverter(String officeHome, int port, String filePath) {
        super();
        this.officeHome = officeHome;
        this.port = port;
        this.filePath = filePath;
    }

    public OpenOfficeConverter(String officeHome, int port) {
        super();
        this.officeHome = officeHome;
        this.port = port;
    }

    public OpenOfficeConverter() {
        super();
    }


    public String getOfficeHome() {
        return officeHome;
    }


    public int getPort() {
        return port;
    }


    public String getFilePath() {
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

}

 

配置類

OpenOfficeConfig.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class OpenOfficeConfig {


    @Bean(initMethod = "init",destroyMethod = "destroy")
    public OpenOfficeConverter openOfficeConverter(){
        return new OpenOfficeConverter();
    }

}

 

文件工具類

FileUtils.java

import java.io.*;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Tom
 */
public class FileUtils {

    public static String getFilePrefix(String fileName) {
        int splitIndex = fileName.lastIndexOf(".");
        return fileName.substring(0, splitIndex);
    }


    public static void copyFile(String inputFile, String outputFile)
            throws FileNotFoundException {
        File sFile = new File(inputFile);
        File tFile = new File(outputFile);
        FileInputStream fis = new FileInputStream(sFile);
        FileOutputStream fos = new FileOutputStream(tFile);
        int temp = 0;
        try {
            while ((temp = fis.read()) != -1) {
                fos.write(temp);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fis.close();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static String toHtmlString(File file) {
        // 獲取HTML文件流
        StringBuffer htmlSb = new StringBuffer();
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    new FileInputStream(file), "gb2312"));
            while (br.ready()) {
                htmlSb.append(br.readLine());
            }
            br.close();
            // 刪除臨時文件
            file.delete();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // HTML文件字符串
        String htmlStr = htmlSb.toString();
        // 返回經過清潔的html文本
        return htmlStr;
    }
    
    
    public static String subString(String html,String prefix,String subfix) {
        return html.substring(html.indexOf(prefix)+prefix.length(), html.indexOf(subfix));
    }

    /**
     * 清除一些不需要的html標記
     * 
     * @param htmlStr
     *            帶有復雜html標記的html語句
     * @return 去除了不需要html標記的語句
     */
    public static String clearFormat(String htmlStr, String docImgPath) {
        // 獲取body內容的正則
        String bodyReg = "<BODY .*</BODY>";
        Pattern bodyPattern = Pattern.compile(bodyReg);
        Matcher bodyMatcher = bodyPattern.matcher(htmlStr);
        if (bodyMatcher.find()) {
            // 獲取BODY內容,並轉化BODY標簽為DIV
            htmlStr = bodyMatcher.group().replaceFirst("<BODY", "<DIV")
                    .replaceAll("</BODY>", "</DIV>");
        }
        // 調整圖片地址
        htmlStr = htmlStr.replaceAll("<IMG SRC=\"", "<IMG SRC=\"" + docImgPath
                + "/");
        // 把<P></P>轉換成</div></div>保留樣式
        // content = content.replaceAll("(<P)([^>]*>.*?)(<\\/P>)",
        // "<div$2</div>");
        // 把<P></P>轉換成</div></div>並刪除樣式
        htmlStr = htmlStr.replaceAll("(<P)([^>]*)(>.*?)(<\\/P>)", "<p$3</p>");
        // 刪除不需要的標簽
        htmlStr = htmlStr
                .replaceAll(
                        "<[/]?(font|FONT|span|SPAN|xml|XML|del|DEL|ins|INS|meta|META|[ovwxpOVWXP]:\\w+)[^>]*?>",
                        "");
        // 刪除不需要的屬性
        htmlStr = htmlStr
                .replaceAll(
                        "<([^>]*)(?:lang|LANG|class|CLASS|style|STYLE|size|SIZE|face|FACE|[ovwxpOVWXP]:\\w+)=(?:'[^']*'|\"\"[^\"\"]*\"\"|[^>]+)([^>]*)>",
                        "<$1$2>");
        return htmlStr;
    }
}

 

 

控制器使用類

OpenOfficeController.java

 

import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.FileCopyUtils;
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.io.File;
import java.io.FileOutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * @author yvioo
 */
@RestController
public class OpenOfficeController {

    public static final DateFormat YEAR_MONTH_FORMAT = new SimpleDateFormat(
            "yyyyMM");


    @Autowired
    private OpenOfficeConverter openOfficeConverter;


    @Value("${fileUploadPath}")
    private String fileUploadPath ;


    @RequestMapping(value = "/o_docUpload", method = RequestMethod.POST)
    public String docUpload(@RequestParam(value = "Filedata", required = false) MultipartFile file) {
        JSONObject data = new JSONObject();
        String origName=file.getOriginalFilename();
        // TODO 檢查允許上傳的后綴

        //先把文件上傳到服務器
        String extName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        String fileName = UUID.randomUUID().toString() + extName;
        //文件所在絕對路徑 上傳路徑和文件名
        String path = fileUploadPath + fileName;
        File toFile=new File(path);
        if (!toFile.getParentFile().exists()){
            //文件夾不存在,先創建文件夾
            toFile.getParentFile().mkdirs();
        }
        try {
            //進行文件復制上傳
            FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(toFile));
        } catch (Exception e) {
            //上傳失敗
            e.printStackTrace();
        }

        //這個是word文檔圖片存放的路徑
        String docImgPath=fileUploadPath+generateMonthname()+"/";
        openOfficeConverter.setFilePath(docImgPath);
        path = path.replace("\\", "/");
        try {
            File outFile = openOfficeConverter.convert(path, OpenOfficeConverter.HTML);
            String html = FileUtils.toHtmlString(outFile);
            String txt = FileUtils.clearFormat(FileUtils.subString(html, "<HTML>", "</HTML>"), docImgPath);
            System.out.println(txt);
            data.put("status", 0);
            data.put("txt", txt);
            data.put("title", origName);
            return  data.toString();
        } catch (Exception e) {
            e.printStackTrace();
            data.put("status", 1);
        }
        return "";
    }


    /**
     * 根據月份生成文件夾名稱
     * @return
     */
    public static String generateMonthname() {
        return YEAR_MONTH_FORMAT.format(new Date());
    }
}

 

 

如果idea啟動報錯了 

Description:

The bean 'openOfficeConverter', defined in class path resource [com/web/openoffice/OpenOfficeConfig.class], could not be registered. A bean with that name has already been defined in file [D:\admin\target\classes\com\web\openoffice\OpenOfficeConverter.class] and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

Disconnected from the target VM, address: '127.0.0.1:50132', transport: 'socket'

Process finished with exit code 0

 

就在application.properties 配置里面增加

spring.main.allow-bean-definition-overriding=true

 

 

如果報錯

Caused by: java.lang.ClassNotFoundException: com.sun.star.lang.XEventListener
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 60 common frames omitted

 

加入maven

 <!-- https://mvnrepository.com/artifact/org.openoffice/ridl -->
        <dependency>
            <groupId>org.openoffice</groupId>
            <artifactId>ridl</artifactId>
            <version>2.2.1</version>
        </dependency>

 

報錯

Caused by: java.util.concurrent.ExecutionException: java.lang.NoClassDefFoundError: com/sun/star/comp/helper/Bootstrap
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at org.artofsolving.jodconverter.office.ManagedOfficeProcess.startAndWait(ManagedOfficeProcess.java:62)
    ... 45 more

 

引入maven

<!-- https://mvnrepository.com/artifact/org.openoffice/juh -->
<dependency>
    <groupId>org.openoffice</groupId>
    <artifactId>juh</artifactId>
    <version>2.2.1</version>
</dependency>

 

報錯

Caused by: java.lang.NoClassDefFoundError: com/sun/star/frame/XComponentLoader
    at org.artofsolving.jodconverter.AbstractConversionTask.loadDocument(AbstractConversionTask.java:86)
    at org.artofsolving.jodconverter.AbstractConversionTask.execute(AbstractConversionTask.java:59)
    at org.artofsolving.jodconverter.office.PooledOfficeManager$2.run(PooledOfficeManager.java:80)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
    at java.util.concurrent.FutureTask.run(FutureTask.java)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    ... 1 more

 

引入

 <!-- https://mvnrepository.com/artifact/org.openoffice/unoil -->
        <dependency>
            <groupId>org.openoffice</groupId>
            <artifactId>unoil</artifactId>
            <version>2.2.1</version>
        </dependency>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM