Word文檔轉換為圖片


實現方式是通過word轉pdf然后在轉換圖片

用到的依賴包

 compile "com.documents4j:documents4j-local:1.0.3"
 compile "com.documents4j:documents4j-transformer-msoffice-word:1.0.3"

實現

package com.viewhigh.epro.svc.util;

import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author qiao
 * @version 1.0
 * @date 2021/8/30 9:43
 */
@Slf4j
public class WordUtil {

    /**
     * word轉pdf
     *
     * @param wordInputStream word輸入流
     * @return pdf字節數據
     */
    public static byte[] wordToPdf(InputStream wordInputStream) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        IConverter converter = LocalConverter.builder().build();
        converter.convert(wordInputStream).as(DocumentType.DOC).to(byteArrayOutputStream).as(DocumentType.PDF).execute();
        return byteArrayOutputStream.toByteArray();
    }

    /**
     * pdf轉圖片
     *
     * @param pdfData pdf字節數據
     * @param scale   圖片比例(A scale of 1 will render at 72 DPI.)
     *                根據需求自行調整,數值過大轉換會慢
     * @return 轉換后圖片數據的字節數組
     */
    @SneakyThrows
    public static List<byte[]> pdfToImage(byte[] pdfData, float scale, boolean isMultiply, Boolean isHorizontal) {
        try (PDDocument doc = PDDocument.load(pdfData)) {
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            List<BufferedImage> bufferedImageList = new ArrayList<>();
            List<byte[]> retList = new ArrayList<>();
            for (int i = 0; i < pageCount; i++) {
                // 第二個參數越大生成圖片分辨率越高,轉換時間也就越長
                BufferedImage image = renderer.renderImage(i, scale);
                bufferedImageList.add(image);

            }
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            if (isMultiply) {
                retList = bufferedImageList.stream().map(item -> {
                    byte[] retBytes = new byte[0];
                    try {
                        ImageIO.write(item, "PNG", byteArrayOutputStream);
                        retBytes = byteArrayOutputStream.toByteArray();
                        byteArrayOutputStream.reset();
                    } catch (IOException e) {
                        log.error("讀取單個圖片流失敗", e);
                    }
                    return retBytes;
                }).collect(Collectors.toList());
            } else {
                //合成圖片
                ImageIO.write(mergeImage(isHorizontal, bufferedImageList.toArray(new BufferedImage[0])), "PNG", byteArrayOutputStream);
                retList.add(byteArrayOutputStream.toByteArray());
            }

            return retList;
        }
    }

    /**
     * word文檔轉換為多張圖(每頁一張)
     * 說明:如果word文檔過大可能會有oom風險,請自行限制大小
     * @param wordInputStream word文檔輸入流
     * @param scale 圖片比例(A scale of 1 will render at 72 DPI.)
     * @return 轉換后圖片數據的字節數組
     */
    public static List<byte[]> wordToMultipleImage(InputStream wordInputStream, float scale) {
        return pdfToImage(wordToPdf(wordInputStream), scale, true, null);
    }

    /**
     * word文檔轉為單張圖
     * 說明:如果word文檔過大可能會有oom風險,請自行限制大小
     * @param wordInputStream word文檔輸入流
     * @param scale 圖片比例(A scale of 1 will render at 72 DPI.)
     * @param isHorizontal true-水平 false-垂直
     * @return 圖片數據字節數組
     */
    public static byte[] wordToMergeImage(InputStream wordInputStream, float scale, Boolean isHorizontal) {
        return pdfToImage(wordToPdf(wordInputStream), scale, false, isHorizontal)
                .stream()
                .findFirst()
                .orElse(null);
    }

    /**
     * 合成多個圖片
     *
     * @param isHorizontal   true-水平 false-垂直
     * @param bufferedImages 多張圖片buffer
     * @return 合成后圖片buffer
     */
    private static BufferedImage mergeImage(Boolean isHorizontal, BufferedImage... bufferedImages) {
        if (isHorizontal == null) {
            isHorizontal = true;
        }
        // 生成新圖片
        BufferedImage destImage;
        // 計算新圖片的長和高
        int allw = 0, allh = 0, maxallw = 0, maxallh = 0;
        // 獲取總長、總寬、最長、最寬
        for (BufferedImage img : bufferedImages) {
            allw += img.getWidth();
            allh += img.getHeight();
            if (img.getWidth() > maxallw) {
                maxallw = img.getWidth();
            }
            if (img.getHeight() > maxallh) {
                maxallh = img.getHeight();
            }
        }
        // 創建新圖片
        if (isHorizontal) {
            destImage = new BufferedImage(allw, maxallh, BufferedImage.TYPE_INT_RGB);
        } else {
            destImage = new BufferedImage(maxallw, allh, BufferedImage.TYPE_INT_RGB);
        }
        // 合並所有子圖片到新圖片
        int wx = 0, wy = 0;
        for (BufferedImage img : bufferedImages) {
            int w1 = img.getWidth();
            int h1 = img.getHeight();
            // 從圖片中讀取RGB
            int[] ImageArrayOne = new int[w1 * h1];
            ImageArrayOne = img.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行掃描圖像中各個像素的RGB到數組中
            if (isHorizontal) { // 水平方向合並
                destImage.setRGB(wx, 0, w1, h1, ImageArrayOne, 0, w1); // 設置上半部分或左半部分的RGB
            } else { // 垂直方向合並
                destImage.setRGB(0, wy, w1, h1, ImageArrayOne, 0, w1); // 設置上半部分或左半部分的RGB
            }
            wx += w1;
            wy += h1;
        }
        return destImage;
    }


    public static void main(String[] args) {
        File inputWord = new File("f:/b.doc");
        InputStream docxInputStream = null;
        try {
            //合成圖
//            docxInputStream = new FileInputStream(inputWord);
//            ImageIO.write(ImageIO.read(new ByteArrayInputStream(wordToMergeImage(docxInputStream, 1.25f, false))), "PNG", new File("F:/HHH.PNG"));

            //多圖
            docxInputStream = new FileInputStream(inputWord);
            for (byte[] data : wordToMultipleImage(docxInputStream, 1.25f)) {
                ImageIO.write(ImageIO.read(new ByteArrayInputStream(data)), "PNG", new File("F:/png/" + System.currentTimeMillis() + ".PNG"));
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (docxInputStream != null) {
                try {
                    docxInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 


免責聲明!

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



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