利用openoffice在web預覽文件

下載openoffice:

進入program目錄後,繼續執行(按原句執行不要更改)
soffice -headless -accept=”socket,host=127.0.0.1,port=8100;urp;” -nofirststartwizard

注意:excel行太長  openoffice解決不了  我在下篇博客會有解決方案

1、pom文件加入

<dependency>
			<groupId>com.artofsolving</groupId>
			<artifactId>jodconverter</artifactId>
			<version>2.2.2</version>
		</dependency>
		<dependency>
			<groupId>org.openoffice</groupId>
			<artifactId>jurt</artifactId>
			<version>3.0.1</version>
		</dependency>
		<dependency>
			<groupId>org.openoffice</groupId>
			<artifactId>ridl</artifactId>
			<version>3.0.1</version>
		</dependency>
		<dependency>
			<groupId>org.openoffice</groupId>
			<artifactId>juh</artifactId>
			<version>3.0.1</version>
		</dependency>
		<dependency>
			<groupId>org.openoffice</groupId>
			<artifactId>unoil</artifactId>
			<version>3.0.1</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.artofsolving.jodconverter/jodconverter-core -->
		<dependency>
			<groupId>org.artofsolving.jodconverter</groupId>
			<artifactId>jodconverter-core</artifactId>
			<version>3.0-beta-4</version>
		</dependency>

 

 

2、轉換的工具類



/**
 * @author gezc30201
 * @description 利用jodconverter(基於OpenOffice服務)將文件(* .doc 、 * .docx  、 * .ppt)轉化爲html格式或者pdf格式,
 *               * .xls、*.xlsx  列太多   會有摺疊問題
 * @date 2020/5/8
 */
@Slf4j
public class Doc2PdfUtil {

    /**
     *@description 轉成pdf流
     * @param fileEnd
         * @param fileInput
     * @return java.io.InputStream
     * @author gezc30201
     * @date 2020/5/8
     */
    public static InputStream doc2pdf(String fileEnd, InputStream fileInput) throws Exception {
        String fileType = "";
        Integer colWidth = 0;

        if (DocEnum.XLSX.getSuffix().equals(fileEnd) || DocEnum.XLS.getSuffix().equals(fileEnd)) { //xlsx格式的文件轉成xls處理    
            ByteArrayOutputStream baos = getByteArrayStream(fileInput); //把輸入流轉成輸出數組的方法
            fileInput = new ByteArrayInputStream(baos.toByteArray());
            InputStream streamClon = new ByteArrayInputStream(baos.toByteArray());
            colWidth = getColumnWidth(streamClon, fileEnd); //獲取excel有數據的列數
            fileType = DocEnum.XLS.getSuffix();
        } else if (DocEnum.DOCX.getSuffix().equals(fileEnd)) {  //docx格式的文件轉成doc處理                   
            fileType = DocEnum.DOC.getSuffix();
        } else {
            fileType = fileEnd;
        }
        try {
            ByteArrayOutputStream pdfstream =convert(fileInput,fileType, colWidth);
            byte[] outbytes = pdfstream.toByteArray();
            InputStream pdfInput = new BufferedInputStream(new ByteArrayInputStream(pdfstream.toByteArray()));//把pdf流轉成輸入流
            pdfstream.flush();
            pdfstream.close();
            return pdfInput;
        } catch (Exception e) {
            log.error(ExceptionUtils.getTrace(e));
            throw new RuntimeException();
        }finally{
            if (fileInput!=null){
                fileInput.close();
            }
        }
    }

    /**
     *@description 描述
     * @param fileEnd
         * @param inbytes
     * @return byte[]
     * @author gezc30201
     * @date 2020/5/9
     */
    public static byte[] doc2pdf(String fileEnd, byte[] inbytes) throws Exception {
        String fileType = "";
        Integer colWidth = 0;
        if (DocEnum.DOCX.getSuffix().equals(fileEnd)) {  //docx格式的文件轉成doc處理                   
            fileType = DocEnum.DOC.getSuffix();
        } else {
            fileType = fileEnd;
        }
        ByteArrayInputStream fileInput=null;
        try {
            fileInput=new ByteArrayInputStream(inbytes);
            ByteArrayOutputStream pdfstream =convert(fileInput,fileType, colWidth);
            byte[] outbytes = pdfstream.toByteArray();
            pdfstream.close();
            return outbytes;
        }catch (Exception e) {
            log.error(ExceptionUtils.getTrace(e));
            throw new RuntimeException();
        }finally{
            if (fileInput!=null){
                fileInput.close();
            }
        }
    }


    /**
     *@description 連接openoffice服務器進行轉換
     * @param fileInput
    	 * @param fileType
    	 * @param colWidth
     * @return java.io.ByteArrayOutputStream
     * @author gezc30201
     * @date 2020/5/9
     */
    private static ByteArrayOutputStream convert( InputStream fileInput, String fileType, int colWidth) {
        OpenOfficeConnection connection =null;
        ByteArrayOutputStream pdfstream=null;
        try {
            connection = new SocketOpenOfficeConnection(8100);
            MyDocumentConverter converter = new MyDocumentConverter(connection, fileType, colWidth); //使用StreamOpenOfficeDocumentConverter可以轉07版的
            DefaultDocumentFormatRegistry formatReg = new DefaultDocumentFormatRegistry(); //jar包裏的類
            DocumentFormat inputFormat = formatReg.getFormatByFileExtension(fileType);  //源文件的格式
            DocumentFormat pdfFormat = formatReg.getFormatByFileExtension("pdf"); //轉成的格式
            pdfstream = new ByteArrayOutputStream();  //保存轉成pdf的流的數組
            converter.convert(fileInput, inputFormat, pdfstream, pdfFormat); //將文件流轉換成pdf流
        }catch (Exception e){
            log.error(ExceptionUtils.getTrace(e));
            throw new RuntimeException();
        }finally {
            connection.disconnect();
        }
        return pdfstream;
    }

    /** 
     *@description 描述 
     * @param fileInput
     * @return java.io.ByteArrayOutputStream
     * @author gezc30201
     * @date 2020/5/9
     */
    private static ByteArrayOutputStream getByteArrayStream(InputStream fileInput) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fileInput.read(buffer)) > -1) {
            baos.write(buffer, 0, len);
        }
        baos.flush();
        return baos;
    }


    /**
     *@description 獲得行的寬度
     * @param fileInput
    	 * @param fileEnd
     * @return java.lang.Integer
     * @author gezc30201
     * @date 2020/5/9
     */
    private static Integer getColumnWidth(InputStream fileInput, String fileEnd) throws Exception {
        Workbook workBook = ExcelUtil.getWorkBook(fileInput, fileEnd);
        int colWidth = 0;
        if (workBook != null) {
            Sheet sheet = workBook.getSheetAt(0);
            if (sheet != null) {
                int colNum = sheet.getRow(1).getPhysicalNumberOfCells();
                for (int i = 0; i < colNum; i++) {
                    colWidth += sheet.getColumnWidth(i);
                }
            }
        }
        workBook.close();
        return colWidth;
    }




   /* public static void excel2pdf(InputStream fromFileInputStream, String toFilePath, String type) throws Exception {

        InputStream is = doc2pdf(type, fromFileInputStream);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timesuffix = sdf.format(new Date());

        File htmlOutputFile = new File(toFilePath + File.separatorChar +timesuffix+ ".pdf");
        if (htmlOutputFile.exists()) {
            htmlOutputFile.delete();
        }
        htmlOutputFile.createNewFile();

        FileOutputStream fos = new FileOutputStream(htmlOutputFile);
        byte[] b = new byte[1024];
        int length;
        while ((length = is.read(b)) > 0){
            fos.write(b,0,length);
        }
        is.close();
        fos.close();

    }

    public static void main(String[] args) throws Exception {
        File file = null;
        FileInputStream fileInputStream = null;

        file = new File("D:\\test\\test.docx");
        fileInputStream = new FileInputStream(file);
        excel2pdf(fileInputStream, "D:\\test\\", "docx");
    }*/

}

openoffice的配置類: 

/***
 *@description openoffice :DOC轉pdf  默認用A4  修改不用A4   excel用ExcelToPdfUtil解決摺疊問題
 * @author gezc30201
 * @date 2020/5/8
 */
@Slf4j
public class MyDocumentConverter extends StreamOpenOfficeDocumentConverter {
    public MyDocumentConverter(OpenOfficeConnection connection){
        super(connection);
    }

    private String fileType;
    private Integer colWidth;

    public MyDocumentConverter(OpenOfficeConnection connection, String fileType, Integer colWidth) {
        super(connection);
        this.colWidth = colWidth;
        this.fileType = fileType;
    }

    public final static Size A4, A3, A2, A1;
    public final static Size B4, B3, B2, B1;
    public final static Size PPTREPORT;

    public final static int KA4= 21000;
    public final static int KA3=29700;
    public final static int KA2=42000;
    public final static int KA1=60000;


    static {
        A4 = new Size(21000, 29700);
        A3 = new Size(29700, 42000);
        A2 = new Size(42000, 59400);
        A1 = new Size(60000, 90000);

        B4 = new Size(25000, 35300);
        B3 = new Size(35300, 50000);
        B2 = new Size(50000, 70700);
        B1 = new Size(70700, 100000);


        PPTREPORT = new Size(25000, 29700);
    }

    @Override
    protected void refreshDocument(XComponent document) {
        super.refreshDocument(document);

        // The default paper format and orientation is A4 and portrait. To
        // change paper orientation
        // re set page size
        XPrintable xPrintable = (XPrintable) UnoRuntime.queryInterface(XPrintable.class, document);
        PropertyValue[] printerDesc = new PropertyValue[3];
        printerDesc[0] = new PropertyValue();
        printerDesc[0].Name = "PaperFormat";
        printerDesc[0].Value = PaperFormat.USER;

        // Paper Size
        printerDesc[1] = new PropertyValue();
        printerDesc[1].Name = "PaperSize";
        /***
         *
         * excel的調整不管用  最多隻能到A3
         *
         */
        if (DocEnum.XLS.getSuffix().equals(fileType)||DocEnum.XLSX.getSuffix().equals(fileType)) {

            if (colWidth <= KA4) {
                printerDesc[1].Value = A4;
            } else if (colWidth > KA4 && colWidth <= KA3) {
                printerDesc[1].Value = A3;
            } else if (colWidth > KA3 && colWidth <= KA2) {
                printerDesc[1].Value = A2;
            } else if (colWidth > KA2 && colWidth <= KA1) {
                printerDesc[1].Value = A1;
            } else {
                printerDesc[1].Value = A4;
            }
            /**
             * ppt用A4的話  會有一點看不到  所以用A3(有空白)
             */
        }else if (DocEnum.PPT.getSuffix().equals(fileType)||DocEnum.PPTX.getSuffix().equals(fileType)){
            printerDesc[1].Value = A3;
        } else {
            printerDesc[1].Value = A4;
        }
        printerDesc[2] = new PropertyValue();
        printerDesc[2].Name = "Pages";
        printerDesc[2].Value = 2;
        try {
            xPrintable.setPrinter(printerDesc);
        } catch (Exception e) {
            log.error(ExceptionUtils.getTrace(e));
        }

    }

}

枚舉類:

/**
 *@description 文件後綴
 * @author gezc30201
 * @date 2020/5/9
 */
public enum DocEnum {

    /**
     * 文件後綴
     */
    DOC(".doc","doc"),
    DOCX(".docx","docx"),
    PPT(".ppt","ppt"),
    PPTX(".pptx","pptx"),
    XLS(".xls","xls"),
    XLSX(".xlsx","xlsx"),
    PDF(".pdf","pdf");

    private String pointSuffix;

    private String suffix;

    DocEnum(String pointSuffix, String suffix) {
        this.pointSuffix = pointSuffix;
        this.suffix = suffix;
    }

    public String getPointSuffix() {
        return pointSuffix;
    }

    public String getSuffix() {
        return suffix;
    }
}

excel兼容工具類:

/**
 *@description 描述
 * @author gezc30201
 * @date 2020/5/8
 */
@Slf4j
public class ExcelUtil {

    public static Workbook getWorkBook(InputStream in, String fileEnd) throws Exception {
        Workbook workbook = null;
        try {
            if (DocEnum.XLS.getSuffix().equals(fileEnd)) { //根據文件後綴名不同(xls和xlsx)獲得不同的Workbook實現類對象
                workbook = new HSSFWorkbook(in);
            } else if (DocEnum.XLSX.getSuffix().equals(fileEnd)) { //2007 及2007以上
                workbook = new XSSFWorkbook(in); //2003
            }
        } catch (Exception e) {
            log.error(ExceptionUtils.getTrace(e));
            return null;
        }
        return workbook;
    }


}

controller:

@GetMapping("/previewAttach")
	public void previewAttach(HttpServletResponse response, @RequestParam(value = "attach_id") String attachId)  {

		DownloadAttach downloadAttach = sysAttachService.downloadAttach(attachId).getResult();
		if (downloadAttach == null || downloadAttach.getBytes() == null) {
			log.warn("附件獲取爲空。附件id:" + attachId.replaceAll("[\r\n]", ""));
			throw new BaseBizException("-1", "附件不存在");
		}
		/*if (!".pdf".equals(downloadAttach.getFileSuffix())){6
			throw new BaseBizException("-1", "只有PDF可以預覽");
		}*/
		if (!DocEnum.PDF.getPointSuffix().equals(downloadAttach.getFileSuffix())&&!DocEnum.XLS.getPointSuffix().equals(downloadAttach.getFileSuffix())&&!DocEnum.XLSX.getPointSuffix().equals(downloadAttach.getFileSuffix())){
			try {
				downloadAttach.setBytes(Doc2PdfUtil.doc2pdf(downloadAttach.getFileSuffix().substring(1),downloadAttach.getBytes()));
			} catch (Exception e) {
				log.error(ExceptionUtils.getTrace(e));
				throw new BaseBizException("-1", "openoffice服務連接不上或者轉換pdf失敗");
			}
		}

		if (DocEnum.XLS.getPointSuffix().equals(downloadAttach.getFileSuffix())||DocEnum.XLSX.getPointSuffix().equals(downloadAttach.getFileSuffix())){
			try {
				downloadAttach.setBytes(ExcelToPdfUtil.excel2pdf(downloadAttach.getBytes()));
			} catch (IOException e) {
				log.error(ExceptionUtils.getTrace(e));
				throw new BaseBizException("-1", "excel轉換pdf失敗");
			}
		}

		OutputStream os = null;
		try {
			response.setHeader("content-length", String.valueOf(downloadAttach.getBytes().length));
			// 預覽
			response.setContentType("application/pdf;charset=utf-8");
			response.setHeader("content-disposition", "inline;filename=" +
			java.net.URLEncoder.encode(downloadAttach.getFileName(), "UTF-8"));
			os = response.getOutputStream();
			//os.write(downloadAttach.getBytes(),0,downloadAttach.getBytes().length);
			int lens = downloadAttach.getBytes().length;
			int flag = 0;
			while (lens > 0){
				os.write(Arrays.copyOfRange(downloadAttach.getBytes(),flag * DOWNLOAD_LENS,(lens > DOWNLOAD_LENS) ? (flag + 1) * DOWNLOAD_LENS : (flag * DOWNLOAD_LENS + lens)));
				flag ++;
				log.info(flag);
				lens -= DOWNLOAD_LENS;
			}
		} catch (Exception e) {
			log.error("預覽附件報錯。附件id:" + attachId.replaceAll("[\r\n]", ""));
			log.error(ExceptionUtils.getTrace(e));
		} finally {
			if (os != null) {
				try {
					os.flush();
					os.close();
				} catch (IOException e) {
					log.error(ExceptionUtils.getTrace(e));
				}
			}
		}
	}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章