天天看點

檔案轉碼(word、ppt、圖檔、Excal)

好久沒和大家見面了,在假期的時候學習了一點關于轉碼的,有一些心得和大家分享一下,希望對你們有所幫助。

1、添加全局配置檔案

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                     
    xmlns:rabbit="http://www.springframework.org/schema/rabbit"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/rabbit
	http://www.springframework.org/schema/rabbit/spring-rabbit-1.4.xsd
	http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context.xsd">
    
	<!-- 定義RabbitMQ的連接配接工廠 -->
	<rabbit:connection-factory id="connectionFactory"
		host="127.0.0.1" port="5672" username="guest" password="guest"
		virtual-host="/" />
		
    <rabbit:admin connection-factory="connectionFactory" />
    
    <!-- spring template聲明 -->
    <rabbit:template exchange="amqpExchange" id="amqpTemplate" connection-factory="connectionFactory" />

    <rabbit:queue name="myQueue" ></rabbit:queue>
 
    <!--聲明 direct 交換模式 -->
    <rabbit:direct-exchange name="amqpExchange">
        <rabbit:bindings>
            <rabbit:binding queue="myQueue" key="queue" ></rabbit:binding>
        </rabbit:bindings>
    </rabbit:direct-exchange>    
	
	<!-- 隊列監聽 -->	
	<bean id="transCodeReceiver" class="com.text.ibo.service.rabbitmq.TransCodeConsumer" />
	<rabbit:listener-container connection-factory="connectionFactory">
		<rabbit:listener ref="transCodeReceiver" method="listen" queue-names="myQueue" />
	</rabbit:listener-container>

</beans>
           

2、安裝相關軟體

1、https://download.csdn.net/download/weixin_40106067/10963320
2、https://download.csdn.net/download/weixin_40106067/10963373
3、rabbitMQ的安裝和配置請參考:https://www.cnblogs.com/LipeiNet/p/5973061.html
           

3、建立工具類

3.1、發送消息隊列

import java.util.Date;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import net.sf.json.JSONObject;

public class MqUtil{
	  
    public static void mqSend(String queueName, 實體類 vo) throws Exception {
        AbstractApplicationContext ctx = new ClassPathXmlApplicationContext(
                "classpath:applicationContext-mq.xml");
        //RabbitMQ模闆
        RabbitTemplate template = ctx.getBean(RabbitTemplate.class);
        template.convertAndSend(queueName, vo);
        System.out.println("[" + new Date() + "]" + "*發送消息隊列*: " + queueName);
        System.out.println("[" + new Date() + "]" + "*發送消息參數*: " + JSONObject.fromObject(vo));
        Thread.sleep(3000);// 休眠3秒
        ctx.close();
    }   
}
           

3.1、office轉PDF工具類

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ConnectException;
import java.util.Date;
import java.util.Properties;
import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;

public class OfficeToPDF {

	/**
	 * 環境變量下面的url.properties的絕對路徑
	 */
	private static final String RUL_PATH = 配置系統虛拟路徑;

	/**
	 * 将Office文檔轉換為PDF. 運作該函數需要用到OpenOffice, OpenOffice下載下傳位址為
	 * http://www.openoffice.org/
	 * 
	 * <pre>
	 * 方法示例:
	 * String sourcePath = "D:\\office\\source.doc";
	 * String destFile = "D:\\office\\dest.pdf";
	 * Converter.office2PDF(sourcePath, destFile);
	 * </pre>
	 * 
	 * @param sourceFile
	 *            源檔案, 絕對路徑. 可以是Office2003-2007全部格式的文檔, Office2010的沒測試. 包括.doc,
	 *            .docx, .xls, .xlsx, .ppt, .pptx等. 示例: D:\\office\\source.doc
	 * @param destFile
	 *            目标檔案. 絕對路徑. 示例: D:\\office\\dest.pdf
	 * @return 操作成功與否的提示資訊. 如果傳回 -1, 表示找不到源檔案, 或url.properties配置錯誤; 如果傳回 0,
	 *         則表示操作成功; 傳回1, 則表示轉換失敗
	 */
	public static int reverse(String sourceFile, String destFile) {
		try {
			File inputFile = new File(sourceFile);
			if (!inputFile.exists()) {
				return -1;// 找不到源檔案, 則傳回-1
			}

			// 如果目标路徑不存在, 則建立該路徑
			File outputFile = new File(destFile);
			if (!outputFile.getParentFile().exists()) {
				outputFile.getParentFile().mkdirs();
			}

			/*
			 * 從url.properties檔案中讀取OpenOffice的安裝根目錄, OpenOffice_HOME對應的鍵值.
			 * 我的OpenOffice是安裝在D:\Program Files\OpenOffice.org 3下面的, 如果大家的
			 * OpenOffice不是安裝的這個目錄下面,需要修改url.properties檔案中的 OpenOffice_HOME的鍵值.
			 * 但是需要注意的是:要用"\\"代替"\",用"\:"代替":" . 如果大家嫌麻煩,
			 * 可以直接給OpenOffice_HOME變量指派為自己OpenOffice的安裝目錄
			 */
			Properties prop = new Properties();
			FileInputStream fis = null;
			fis = new FileInputStream(RUL_PATH);// 屬性檔案輸入流
			prop.load(fis);// 将屬性檔案流裝載到Properties對象中
			fis.close();// 關閉流

			String OpenOffice_HOME = prop.getProperty("OpenOffice_HOME");
			if (OpenOffice_HOME == null)
				return -1;
			// 如果從檔案中讀取的URL位址最後一個字元不是 '\',則添加'\'
			if (OpenOffice_HOME.charAt(OpenOffice_HOME.length() - 1) != '\\') {
				OpenOffice_HOME += "\\";
			}
			// 啟動OpenOffice的服務
			String command = OpenOffice_HOME
					+ "program\\soffice.exe -headless -accept=\"socket,host=127.0.0.1,port=8100;urp;\" -nofirststartwizard";
			Process pro = Runtime.getRuntime().exec(command);
			System.out.println("[" + new Date() + "]" + "*啟動OpenOffice服務*");
			
			// connect to an OpenOffice.org instance running on port 8100
			OpenOfficeConnection connection = new SocketOpenOfficeConnection(
					"127.0.0.1", 8100);
			//Thread.sleep(2000);// 休眠2秒 要連接配接openoffice需要等待soffice關聯啟動soffice.bin
			
	        // 連接配接             
	        long con_s=System.currentTimeMillis();     
	        connection.connect();     
	        long con_e=System.currentTimeMillis();    
	        if(connection.isConnected()) {
	        	System.out.println("[" + new Date() + "]" + "*OpenOffice連接配接成功*, 耗時:" + (con_e-con_s)/1000 + "." + (con_e-con_s)%1000 + "s");   
	        }else {
	        	System.out.println("[" + new Date() + "]" + "*OpenOffice連接配接失敗* , 耗時:" + (con_e-con_s)/1000 + "." + (con_e-con_s)%1000 + "s");
	        }

			System.out.println("[" + new Date() + "]" + "*OpenOffice轉換開始*");
			// convert //StreamOpenOfficeDocumentConverter //OpenOfficeDocumentConverter
			DocumentConverter converter = new OpenOfficeDocumentConverter(
					connection);
			
			//轉換
			long dc_s=System.currentTimeMillis();
			converter.convert(inputFile, outputFile);		
		    long dc_e=System.currentTimeMillis();     
		    System.out.println("[" + new Date() + "]" + "*OpenOffice轉換結束* "+ ",耗時:" + (dc_e-dc_s)/1000 + "." + (dc_e-dc_s)%1000 + "s");     
;
			// close the connection
			connection.disconnect();
			// 關閉OpenOffice服務的程序
			pro.destroy();
			System.out.println("[" + new Date() + "]" + "*關閉OpenOffice服務*");
			return 0;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return -1;
		} catch (ConnectException e) {
			e.printStackTrace();
			System.out.println("[" + new Date() + "]" + "*OpenOffice連接配接異常檔案轉換出錯,請檢查本機是否安裝OpenOffice或者OpenOffice服務是否啟動。*");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return 1;
	}
}
           

3.3、圖檔轉PDF工具類

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.io.RandomAccessFile;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDCcitt;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDPixelMap;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
import org.apache.pdfbox.util.PDFTextStripper;

public class TuToPDF {

	
	/**
	 * PDF檔案插入圖檔
	 * 
	 * @param inputFile  The input PDF to add the image to.
	 * @param image      The filename of the image to put in the PDF.
	 * @param outputFile The file to write to the pdf to.
	 *
	 * @throws IOException         If there is an error writing the data.
	 * @throws COSVisitorException If there is an error writing the PDF.
	 */
	public static int reverse(String inputFile, String image, String outputFile) {		
		try {	
			// 建立pdf檔案模闆
	        PDDocument document = new PDDocument();  			
	        BufferedImage sourceImg =ImageIO.read(new FileInputStream(image)); 
	        //擷取圖檔尺寸并設定PDF尺寸
	        PDPage ppap = new PDPage(new PDRectangle(sourceImg.getWidth(), sourceImg.getHeight()));  
	        document.addPage(ppap);    	          
	        PDPageContentStream stream = new PDPageContentStream(document, ppap);              
	        stream.close();            
	        document.save(inputFile);
	        document.close();  			        
			//文檔
			PDDocument doc = null;
			doc = PDDocument.load(inputFile);
			//添加圖檔到第一頁
			PDPage page = (PDPage) doc.getDocumentCatalog().getAllPages().get(0);
			PDXObjectImage ximage = null;
			if (image.toLowerCase().endsWith(".jpg")) {
				ximage = new PDJpeg(doc, new FileInputStream(image));
			} else if (image.toLowerCase().endsWith(".tif") || image.toLowerCase().endsWith(".tiff")) {
				ximage = new PDCcitt(doc, new RandomAccessFile(new File(image), "r"));
			} else {
				BufferedImage awtImage = ImageIO.read(new File(image));
				ximage = new PDPixelMap(doc, awtImage);
			}
			PDPageContentStream contentStream = new PDPageContentStream(doc, page, true, true);
			float scale = 1f; // 減少此值防止圖檔過大
			contentStream.drawXObject(ximage, 0, 0, ximage.getWidth() * scale, ximage.getHeight() * scale);
			contentStream.close();
			doc.save(outputFile);
			if (doc != null) {
				doc.close();
			}			
			File file = new File(inputFile);
			if (file.exists()) {			
				file.delete(); //删除模闆檔案
			}			
			return 0;
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}
	}
}
           

4、建立一個消費者,用于監聽消息-轉碼

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import net.sf.json.JSONObject;

public class TransCodeConsumer {

	// 監聽資源上傳-公用
	public void listen(TransCodeVo vo) {
		System.out.println("[" + new Date() + "]" + "*消費者捕獲隊列,開始消費*");
		System.out.println("[" + new Date() + "]" + "*接收消息參數*:" + JSONObject.fromObject(vo));
		System.out.println("[" + new Date() + "]" + "*檔案轉碼開始*");
		try {
			// 更新轉碼狀态
			vo.setConvertStatus("P"); // P轉碼中

			// 擷取檔案路徑
			int status = -1; // 工具類轉碼狀态
			String resourceUrl = vo.getResourceUrl(); // 源檔案絕對路徑
			String fileType = null;
			//String resourceUrl = xxx; // 源檔案絕對路徑
			if (resourceUrl != null) {
				if("alternativeresources".equals(vo.getTableName().toLowerCase())) {
					fileType = 檔案類型.toLowerCase();
				}else {
					fileType = resourceUrl.substring(resourceUrl.indexOf(".")+1).toLowerCase();
				}
				
			} else {
				return;
			}
			String fileName = resourceUrl.substring(resourceUrl.lastIndexOf("/") + 1, resourceUrl.lastIndexOf(".")); // 檔案名
			String tansCodePath = xxx;//檔案絕對路徑
			String resourceViewUrl = tansCodePath + fileName + ".pdf"; // 目标檔案絕對路徑			
			
			// 轉碼
			if ("doc".equals(fileType) || "docx".equals(fileType) || "xls".equals(fileType) || "xlsx".equals(fileType)
					|| "ppt".equals(fileType) || "pptx".equals(fileType) || "wps".equals(fileType)) {
				status = OfficeToPDF.reverse(resourceUrl, resourceViewUrl);
			} else if ("jpeg".equals(fileType) || "jpg".equals(fileType) || "bmp".equals(fileType)
					|| "png".equals(fileType)) {		   
				String inputFile = tansCodePath + "demo.pdf";			
				status = TuToPDF.reverse(inputFile, resourceUrl, resourceViewUrl);
			} 
			if (status == 0) {
				System.out.println("[" + new Date() + "]" + "*轉碼成功*: " + resourceUrl + " ----> " + resourceViewUrl);
				// 将更新後的轉碼視圖位址 轉碼狀态儲存
				vo.setConvertStatus("C"); // C已完成
				vo.setResourceViewUrl(resourceViewUrl);
				int count = update語句;
				if (count > 0) {
					System.out.println("[" + new Date() + "]" + "*更新轉碼位址成功*");
				} else {
					System.out.println("[" + new Date() + "]" + "*轉碼位址未更新*");
				}
			} else {
				System.out.println("[" + new Date() + "]" + "*轉碼失敗*: 暫不支援. " + fileType + "類型檔案轉碼");
				vo.setConvertStatus("E"); // E錯誤
				update語句;
			}
			System.out.println("[" + new Date() + "]" + "*檔案轉碼結束*");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("[" + new Date() + "]" + "*檔案轉碼異常*");
			vo.setConvertStatus("E"); // E錯誤
			update語句;
		}
	}	

}