最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實現(xiàn)將Word和PDF轉(zhuǎn)成一張垂直拼接長圖的工具類

 更新時間:2025年10月15日 08:54:11   作者:Uluoyu  
這篇文章主要為大家詳細介紹了如何使用Java編寫一個將Word和PDF轉(zhuǎn)成一張垂直拼接長圖的工具類,支持doc和docx,有需要的小伙伴可以了解下

1.添加依賴

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.5</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>5.2.5</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.5</version> <!-- 如果有 DOCX 相關(guān) -->
</dependency>
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>3.0.5</version>
</dependency>
<!-- Word轉(zhuǎn)PDF:Docx4J核心 -->
        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j-JAXB-ReferenceImpl</artifactId>
            <version>8.3.10</version>
        </dependency>

        <!-- Word轉(zhuǎn)PDF:FO導(dǎo)出支持(用于PDF渲染) -->
        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j-export-fo</artifactId>
            <version>8.3.10</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.3</version>
        </dependency>
        <!-- 如果 Docx4J 版本舊,還可能需激活模塊 -->
        <dependency>
            <groupId>com.sun.activation</groupId>
            <artifactId>javax.activation</artifactId>
            <version>1.2.0</version>
        </dependency>

2.Java代碼

import lombok.extern.slf4j.Slf4j;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.io.RandomAccessReadBuffer;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.WordToFoConverter;
import org.docx4j.Docx4J;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.w3c.dom.Document;

import javax.imageio.ImageIO;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description 文檔轉(zhuǎn)長圖片工具類
 * 支持Word (doc/docx) 和 PDF 轉(zhuǎn)成一張垂直拼接的長PNG圖片
 */

@Slf4j
public class DocumentToImageUtil {

    /**
     * 將文檔(Word或PDF)轉(zhuǎn)換為長圖片字節(jié)數(shù)組
     * @param content 文檔字節(jié)數(shù)組
     * @param fileType 文件類型(doc, docx, pdf)
     * @return PNG圖片字節(jié)數(shù)組
     * @throws IOException 轉(zhuǎn)換失敗
     */
    public byte[] convertToStitchedImage(byte[] content, String fileType) throws IOException {
        byte[] pdfContent = content;
        if (fileType.toLowerCase().contains("doc") || fileType.toLowerCase().contains("docx")) {
            pdfContent = convertWordToPdf(content, fileType.toLowerCase());
        }
        return convertPdfToStitchedImage(pdfContent);
    }

    /**
     * Word轉(zhuǎn)PDF(支持doc和docx)
     */
    private byte[] convertWordToPdf(byte[] wordContent, String fileType) throws IOException {
        if (fileType.toLowerCase().contains("docx")) {
            // DOCX轉(zhuǎn)PDF使用Docx4J
            try (ByteArrayInputStream bais = new ByteArrayInputStream(wordContent)) {
                WordprocessingMLPackage loadedPackage = WordprocessingMLPackage.load(bais);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                Docx4J.toPDF(loadedPackage, baos);
                return baos.toByteArray();
            } catch (Exception e) {
                throw new IOException("DOCX轉(zhuǎn)PDF失敗", e);
            }
        } else if (fileType.toLowerCase().contains("doc")) {
            // DOC轉(zhuǎn)PDF使用POI HWPF + Transformer + FOP
            try (ByteArrayInputStream bais = new ByteArrayInputStream(wordContent);
                 HWPFDocument document = new HWPFDocument(bais)) {

                // 1. 使用 WordToFoConverter 生成 FO Document(移除 setFontResolver,使用默認)
                Document foDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
                WordToFoConverter converter = new WordToFoConverter(foDoc);
                // 注意:在 POI 5.2.5 中,setFontResolver 已棄用或移除,使用默認字體解析器
                converter.processDocument(document);

                // 2. Transformer 將 FO Document 序列化為字節(jié)流
                ByteArrayOutputStream foBaos = new ByteArrayOutputStream();
                TransformerFactory tf = TransformerFactory.newInstance();
                Transformer serializer = tf.newTransformer();
                serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
                serializer.setOutputProperty(OutputKeys.INDENT, "yes");
                serializer.setOutputProperty(OutputKeys.METHOD, "xml"); // 輸出 XML-FO
                serializer.transform(new DOMSource(foDoc), new StreamResult(foBaos));
                byte[] foBytes = foBaos.toByteArray();

                // 3. FOP 將 FO 轉(zhuǎn) PDF(使用帶URI參數(shù)的newInstance,避免解析問題)
                FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); // 標準方式,設(shè)置base URI
                ByteArrayOutputStream pdfBaos = new ByteArrayOutputStream();
                Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, pdfBaos);
                Transformer transformer = tf.newTransformer(); // 身份轉(zhuǎn)換器
                Source src = new StreamSource(new ByteArrayInputStream(foBytes));
                Result res = new SAXResult(fop.getDefaultHandler());
                transformer.transform(src, res);

                return pdfBaos.toByteArray();
            } catch (Exception e) {
                throw new IOException("DOC轉(zhuǎn)PDF失敗", e);
            }
        } else {
            throw new IOException("不支持的文件類型: " + fileType);
        }
    }

    /**
     * PDF轉(zhuǎn)垂直拼接的長圖片
     */
    private byte[] convertPdfToStitchedImage(byte[] pdfContent) throws IOException {
        try (ByteArrayInputStream bais = new ByteArrayInputStream(pdfContent);
             RandomAccessReadBuffer buffer = new RandomAccessReadBuffer(bais);
             PDDocument document = Loader.loadPDF(buffer)) {
            PDFRenderer renderer = new PDFRenderer(document);
            int numPages = document.getNumberOfPages();
            if (numPages == 0) {
                return null;
            }

            List<BufferedImage> pageImages = new ArrayList<>();
            int totalHeight = 0;
            int maxWidth = 0;
            for (int i = 0; i < numPages; i++) {
                BufferedImage pageImage = renderer.renderImageWithDPI(i, 150);
                pageImages.add(pageImage);
                totalHeight += pageImage.getHeight();
                maxWidth = Math.max(maxWidth, pageImage.getWidth());
            }

            BufferedImage stitchedImage = new BufferedImage(maxWidth, totalHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = stitchedImage.createGraphics();
            g2d.setBackground(java.awt.Color.WHITE);
            g2d.clearRect(0, 0, maxWidth, totalHeight);

            int yOffset = 0;
            for (BufferedImage pageImage : pageImages) {
                g2d.drawImage(pageImage, 0, yOffset, null);
                yOffset += pageImage.getHeight();
            }
            g2d.dispose();

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(stitchedImage, "png", baos);
            return baos.toByteArray();
        } catch (Exception e) {
            throw new IOException("PDF轉(zhuǎn)圖片失敗", e);
        }
    }
}

3.如何使用

byte[] imageBytes = new DocumentToImageUtil().convertToStitchedImage(content, fileType.toLowerCase());

到此這篇關(guān)于Java實現(xiàn)將Word和PDF轉(zhuǎn)成一張垂直拼接長圖的工具類的文章就介紹到這了,更多相關(guān)Java Word和PDF轉(zhuǎn)圖片內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中的悲觀鎖與樂觀鎖是什么

    Java中的悲觀鎖與樂觀鎖是什么

    這篇文章主要介紹了Java中的悲觀鎖與樂觀鎖是什么,幫助大家更好的理解和學(xué)習(xí)Java鎖的相關(guān)知識,感興趣的朋友可以了解下
    2020-09-09
  • Java中接口Set的特點及方法說明

    Java中接口Set的特點及方法說明

    這篇文章主要介紹了Java中接口Set的特點及方法說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java對象創(chuàng)建的過程流程分析

    Java對象創(chuàng)建的過程流程分析

    本文詳細介紹了Java對象創(chuàng)建的整個過程,包括類加載、內(nèi)存分配、對象頭設(shè)置、構(gòu)造器初始化以及內(nèi)存分配的安全問題,文章還討論了新生代和老年代的內(nèi)存分配策略,特別是使用指針碰撞和空閑列表兩種方式,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • SPRINGMVC 406問題解決方案

    SPRINGMVC 406問題解決方案

    這篇文章主要介紹了SPRINGMVC 406問題解決方案,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • java中循環(huán)刪除list中元素的方法總結(jié)

    java中循環(huán)刪除list中元素的方法總結(jié)

    下面小編就為大家?guī)硪黄猨ava中循環(huán)刪除list中元素的方法總結(jié)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • IDEA 2020代碼提示忽略大小寫的問題

    IDEA 2020代碼提示忽略大小寫的問題

    這篇文章主要介紹了IDEA 2020代碼提示忽略大小寫的問題,本文通過圖文并茂的形式給大家分享解決方法,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Java14發(fā)布了,再也不怕NullPointerException了

    Java14發(fā)布了,再也不怕NullPointerException了

    這篇文章主要介紹了Java14發(fā)布了,再也不怕NullPointerException了,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2020-03-03
  • Java和C的隨機數(shù)(Random)詳解

    Java和C的隨機數(shù)(Random)詳解

    本篇文章主要介紹了Java和C隨機數(shù)(Random),現(xiàn)在分享給大家,也給大家做個參考,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-09-09
  • Java嵌套for循環(huán)優(yōu)化方案分享

    Java嵌套for循環(huán)優(yōu)化方案分享

    介紹了Java中嵌套for循環(huán)的優(yōu)化方法,包括減少循環(huán)次數(shù)、合并循環(huán)、使用更高效的數(shù)據(jù)結(jié)構(gòu)、并行處理、預(yù)處理和緩存、算法優(yōu)化、盡量減少對象創(chuàng)建以及本地變量優(yōu)化,通過這些方法,可以顯著提升程序的執(zhí)行效率,文章還以動態(tài)規(guī)劃優(yōu)化示例——最長遞增子序列
    2025-03-03
  • spring boot@EnableXXXX注解編程模型講解

    spring boot@EnableXXXX注解編程模型講解

    這篇文章主要介紹了spring boot@EnableXXXX注解編程模型,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評論

新沂市| 麻江县| 中西区| 马关县| 遂平县| 称多县| 绍兴市| 新邵县| 兰坪| 始兴县| 且末县| 宝丰县| 蒙自县| 大渡口区| 南昌县| 肥东县| 揭东县| 松滋市| 信丰县| 青阳县| 湖南省| 偃师市| 南开区| 东乡族自治县| 赫章县| 马尔康县| 岳西县| 革吉县| 乌拉特中旗| 嫩江县| 新源县| 望江县| 滦平县| 清远市| 突泉县| 元氏县| 嘉善县| 佛冈县| 英德市| 德化县| 洛南县|