2025-01-08
技术分享
00
请注意,本文编写于 146 天前,最后修改于 91 天前,其中某些信息可能已经过时。

目录

Jaocb_v1.21调用WPS COM组件😀👍

Jaocb_v1.21调用WPS COM组件😀👍

https://sourceforge.net/projects/jacob-project/

https://sourceforge.net/projects/jacob-project/

java
package top.zhoudeshui.utils; import com.jacob.activeX.ActiveXComponent; import com.jacob.com.ComThread; import com.jacob.com.Dispatch; import com.jacob.com.Variant; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.concurrent.*; public class WPSConvertUtils { private static final Logger logger = LoggerFactory.getLogger(WPSConvertUtils.class); private static final int WD_FORMAT_PDF = 17; private static final int XL_TYPE_PDF = 0; private static final int PP_SAVE_AS_PDF = 32; private static final ExecutorService executorService = Executors.newSingleThreadExecutor(); public static CompletableFuture<String> convertToPDF(String inputFilePath, String outputDirOrFilePath) { File inputFile = new File(inputFilePath); if (!inputFile.exists()) { logger.warn("原文件不存在: {}", inputFilePath); return CompletableFuture.completedFuture(null); } String kind = getFileSuffix(inputFile.getName()); // 检查文件是否为PDF if ("pdf".equalsIgnoreCase(kind)) { try { Path source = new File(inputFilePath).toPath(); Path target = new File(outputDirOrFilePath).toPath(); // 检查源文件是否存在 if (!Files.exists(source)) { logger.error("Source file does not exist: {}", source); return CompletableFuture.completedFuture(null); } // 如果目标是目录,创建一个以源文件名命名的新文件 if (Files.isDirectory(target)) { target = target.resolve(source.getFileName()); } // 确保目标目录存在 Path targetParent = target.getParent(); if (targetParent != null && !Files.exists(targetParent)) { Files.createDirectories(targetParent); } Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); logger.info("PDF 文件已复制: {} -> {}", source, target); return CompletableFuture.completedFuture(target.toString()); } catch (IOException e) { logger.error("Error copying PDF file", e); return CompletableFuture.completedFuture(null); } } String baseName = inputFile.getName().substring(0, inputFile.getName().lastIndexOf(".")); File outputDirOrFile = new File(outputDirOrFilePath); String outputFilePath; // 检查输出路径是否包含.pdf if (outputDirOrFilePath.toLowerCase().endsWith(".pdf")) { // 输出路径已经包含.pdf,直接使用该文件名 File pdfFile = new File(outputDirOrFilePath); // 确保文件的父目录存在,如果不存在则创建 if (!pdfFile.getParentFile().exists() && !pdfFile.getParentFile().mkdirs()) { logger.error("创建目录失败,请检查目录权限!"); return CompletableFuture.completedFuture(null); } outputFilePath = outputDirOrFilePath; } else { // 输出路径不包含.pdf,使用源文件的基本名称作为输出文件名 if (!outputDirOrFile.exists() && !outputDirOrFile.mkdirs()) { logger.error("创建目录失败,请检查目录权限!"); return CompletableFuture.completedFuture(null); } outputFilePath = new File(outputDirOrFile, baseName + ".pdf").getAbsolutePath(); } // 提交任务到线程池并返回 CompletableFuture return CompletableFuture.supplyAsync(() -> processTask(inputFilePath, outputFilePath, kind), executorService) .thenApply(result -> { if (result) { logger.info("转换成功: {} -> {}", inputFilePath, outputFilePath); return outputFilePath; } else { logger.error("转换失败: {}", inputFilePath); return null; } }); } private static boolean processTask(String inputFilePath, String outputFilePath, String kind) { switch (kind.toLowerCase()) { case "doc": case "docx": case "txt": return wordToPDF(inputFilePath, outputFilePath); case "ppt": case "pptx": case "pptm": case "ppsx": return pptToPDF(inputFilePath, outputFilePath); case "xls": case "xlsx": return exToPDF(inputFilePath, outputFilePath); case "png": case "jpg": case "jpeg": case "gif": return imageToPDF(inputFilePath, outputFilePath); default: logger.warn("不支持的文件格式: {}", kind); return false; } } private static String getFileSuffix(String fileName) { int splitIndex = fileName.lastIndexOf("."); return splitIndex == -1 ? "" : fileName.substring(splitIndex + 1); } private static boolean wordToPDF(String inputFile, String pdfFile) { ActiveXComponent app = null; try { ComThread.InitSTA(); app = new ActiveXComponent("KWPS.Application"); app.setProperty("Visible", new Variant(false)); app.setProperty("AutomationSecurity", new Variant(3)); // 禁用宏 Dispatch docs = app.getProperty("Documents").toDispatch(); Dispatch doc = Dispatch.call(docs, "Open", inputFile, false, true).toDispatch(); Dispatch.call(doc, "ExportAsFixedFormat", pdfFile, WD_FORMAT_PDF); Dispatch.call(doc, "Close", false); logger.info("Word 文件转换成功: {} -> {}", inputFile, pdfFile); return true; } catch (Exception e) { logger.error("Word 文件转换失败: {}", inputFile, e); return false; } finally { if (app != null) { app.invoke("Quit", 0); app.safeRelease(); // 释放 ActiveXComponent 资源 } ComThread.Release(); } } private static boolean exToPDF(String inputFile, String pdfFile) { ActiveXComponent app = null; try { ComThread.InitSTA(); app = new ActiveXComponent("KET.Application"); app.setProperty("Visible", new Variant(false)); app.setProperty("AutomationSecurity", new Variant(3)); // 禁用宏 Dispatch excels = app.getProperty("Workbooks").toDispatch(); Dispatch excel = Dispatch.invoke(excels, "Open", Dispatch.Method, new Object[]{inputFile, new Variant(false), new Variant(false)}, new int[9]).toDispatch(); Dispatch.invoke(excel, "ExportAsFixedFormat", Dispatch.Method, new Object[]{new Variant(XL_TYPE_PDF), pdfFile}, new int[1]); Dispatch.call(excel, "Close", new Variant(false)); logger.info("Excel 文件转换成功: {} -> {}", inputFile, pdfFile); return true; } catch (Exception e) { logger.error("Excel 文件转换失败: {}", inputFile, e); return false; } finally { if (app != null) { app.invoke("Quit"); app.safeRelease(); // 释放 ActiveXComponent 资源 } ComThread.Release(); } } private static boolean pptToPDF(String inputFile, String pdfFile) { ActiveXComponent app = null; try { ComThread.InitSTA(); app = new ActiveXComponent("KWPP.Application"); Dispatch ppts = app.getProperty("Presentations").toDispatch(); Dispatch ppt = Dispatch.call(ppts, "Open", inputFile, true, false).toDispatch(); Dispatch.invoke(ppt, "SaveAs", Dispatch.Method, new Object[]{pdfFile, new Variant(PP_SAVE_AS_PDF)}, new int[1]); Dispatch.call(ppt, "Close"); logger.info("PPT 文件转换成功: {} -> {}", inputFile, pdfFile); return true; } catch (Exception e) { logger.error("PPT 文件转换失败: {}", inputFile, e); return false; } finally { if (app != null) { app.invoke("Quit"); app.safeRelease(); // 释放 ActiveXComponent 资源 } ComThread.Release(); } } /** * 将图片转换为PDF * * @param inputFile 图片文件路径 * @param pdfFile 输出PDF文件路径 * @return 是否转换成功 */ public static boolean imageToPDF(String inputFile, String pdfFile) { try (PDDocument document = new PDDocument()) { PDPage page = new PDPage(PDRectangle.A4); // 创建一个A4页面 document.addPage(page); // 加载图片并创建一个PDF图像对象 File file = new File(inputFile); BufferedImage bufferedImage = ImageIO.read(file); PDImageXObject pdImage = LosslessFactory.createFromImage(document, bufferedImage); // 计算图片缩放比例以适应页面 float originalWidth = pdImage.getWidth(); float originalHeight = pdImage.getHeight(); float scaleX = PDRectangle.A4.getWidth() / originalWidth; float scaleY = PDRectangle.A4.getHeight() / originalHeight; float scale = Math.min(scaleX, scaleY); // 取较小的缩放比例以完全适应页面 // 开始在页面上绘制内容 try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) { // 将图片绘制到页面上,居中并按比例缩放 float x = (PDRectangle.A4.getWidth() - originalWidth * scale) / 2; float y = (PDRectangle.A4.getHeight() - originalHeight * scale) / 2; contentStream.drawImage(pdImage, x, y, originalWidth * scale, originalHeight * scale); } // 保存PDF文件 document.save(pdfFile); logger.info("图片转换成功: {} -> {}", inputFile, pdfFile); return true; } catch (IOException e) { logger.error("图片转换失败: {}", inputFile, e); return false; } } }

本文作者:周得水

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!