본문 바로가기

Web

jpg파일 여러장 pdf로 변환하기

728x90
반응형

프로젝트 중에 jpg파일 여러장을 하나의 pdf로 변환해야하는 일이 생겼다.

하나의 도서를 페이지 별로 한장 한장 전달 받아서 한 권의 도서를 만들어야했던 것이다.

 

본인은 처음에 이 작업을 코드로 할 생각조차 못했다.

그래서 jpg를 pdf로 변환 해주는 웹 사이트를 찾아보고 있던 와중에 '자바 코드로 왠지 될 거 같은데?' 라는 생각이 들어서 시도 해봤다.

 

일단 사용한 라이브러리는 Apache에서 제공하는 pdfbox라는 라이브러리이다.

 

본인이 진행중인 프로젝트는 Maven 프로젝트이기 때문에 pom.xml에 라이브러리를 추가했다.


<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.24</version>
</dependency>

 

이후 

컨트롤러에서 코드를 작성해주었다. 

(주석으로 세세한 설명을 적어놨다.)

package com.ttcc.wssd.common.app.controller;


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.PDImageXObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.imageio.ImageIO;
import java.awt.*;
import java.io.File;
import java.util.Arrays;

@Controller
@RequestMapping("/pdfConvert")
public class JpgToPdfFileController {

    @RequestMapping("/pdf.do")
    public static void createPdf() throws Exception {
        String result = "";

        try {

            String goFolder = "C:/Users/Developer/Desktop/새폴더";
            File goFolderFile = new File(goFolder);
            int goFolderLength = goFolderFile.list().length;
            String[] fileArray = goFolderFile.list();

            // 폴더들을 이름순으로 정렬
            Arrays.sort(fileArray);

            for (int k = 0; k < goFolderLength; k++) {

                String imageFolder = goFolder + "/" + fileArray[k];

                System.err.println("imageFolder = " + fileArray[k]);

                System.err.println("imageFolderName = " + goFolderFile.getName());


                File folder = new File(imageFolder);
                int length = folder.list().length;

                for (int j = 0; j < length; j++) {

                    String pdfName = "";
                    String pdfDir = folder.list()[j];
                    String imageFolder2 = imageFolder + "/" + folder.list()[j];

                    // 폴더 이름이 알파뱃 2글자 + 숫자 3~5자리임 ex) AI1234
                    String firstName = pdfDir.substring(0, 2);
                    String secondName = pdfDir.substring(2, pdfDir.length());

                    // pdf 파일 이름에 규칙성을 부여하기 위해
                    if (secondName.length() == 3) {
                        pdfName = firstName + "U000000" + secondName;
                    }
                    if (secondName.length() == 4) {
                        pdfName = firstName + "U00000" + secondName;
                    }
                    if (secondName.length() == 5) {
                        pdfName = firstName + "U0000" + secondName;
                    }
                    if (secondName.length() == 6) {
                        pdfName = firstName + "U000" + secondName;
                    }
                    System.err.println("pdfName = " + pdfName);

                    File dir = new File(imageFolder2);

                    //Post를 통해 생성할 이미지를 가져옴
                    File[] imgFiles = dir.listFiles();

                    //PDF 문서를 생성함
                    PDDocument doc = new PDDocument();

                    //첨부된 이미지 파일 갯수만큼 반복문 실행
                    for (int i = 0; i < imgFiles.length; i++) {

                        System.err.println("루프도는 중..." + i);

                        //이미지 사이즈 확인
                        Image img = ImageIO.read(imgFiles[i]);

                        //PDF 페이지를 생성함
                        PDPage page = new PDPage(PDRectangle.A4);

                        doc.addPage(page);

                        //PDF에 삽입할 이미지 인자값 - 이미지경로, PDF 페이지
                        PDImageXObject pdImage = PDImageXObject.createFromFile(imgFiles[i].toString(), doc);

                        //현재 설정된 PDF 페이지의 가로/세로 구하기
                        int pageWidth = Math.round(page.getCropBox().getWidth());
                        int pageHeight = Math.round(page.getCropBox().getHeight());

                        //이미지 가로사이즈가 PDF 가로사이즈보다 클 경우를 대비해서 이미지 리사이징 실행
                        //현재 설정된 PDF 페이지 가로 , 이미지 가로 사이즈로 비율 측정 
                        float imgWidthRatio = 1;
                        float imgHeightRatio = 1;
                        if (pageWidth < img.getWidth(null)) {
                            imgWidthRatio = (float) img.getWidth(null) / (float) pageWidth;
                            imgHeightRatio = (float) img.getHeight(null) / (float) pageHeight;
                        }

                        //이미지 비율 다시 맞추기
                        int imgWidth = Math.round(img.getWidth(null) / imgWidthRatio);
                        int imgHeight = Math.round(img.getHeight(null) / imgHeightRatio);

                        //가운데 정렬
                        int pageWidthPosition = (pageWidth - imgWidth) / 2;
                        int pageHeightPosition = (pageHeight - imgHeight) / 2;
                        PDPageContentStream contents = new PDPageContentStream(doc, page);
                        contents.drawImage(pdImage, pageWidthPosition, pageHeightPosition, imgWidth, imgHeight);
                        //콘텐츠에 이미지를 다 그렸으면 콘텐츠를 종료
                        contents.close();

                    }
                    //pdf 저장
                    doc.save("C:/Users/Developer/Desktop/새폴더/" + pdfName + ".pdf");

                    result = "success";

                    //document 닫아주기(1개 pdf가 완성 됐을 때 잘 닫아주지 않으면 다음 pdf는 이전 pdf와 중복돼서 만들어짐)
                    doc.close();
                }
            }

        } catch (Exception e) {
            result = "error";
            System.out.println("Exception! : " + e.getMessage());
        }
        System.err.println(result);
    }

}
   

일단 본인의 상황은 폴더가 총 3개의 depth를 가지고 있다.

1개 폴더 -> 여러개 폴더 -> 여러장의 jpg

 

쉽게 예를 들면 '새폴더'라는 폴더 안에 '어린왕자', '홍길동', '개미', '파피용'...등의 폴더가 있고 각각의 폴더 안에 도서의 각페이지 별로 jpg가 들어있는 것이다.

 

그래서 본인은 3번의 반복문을 사용하게 되었다.

(이러한 상황이 아니라면 상위 2개 반복문은 제거하고 사용해도 무방하다.

 

이렇게 코드를 짜고 로컬에서 서버를 구동한 후에 localhost:8080/pdfConvert/pdf.do를 호출해주면 알아서 폴더내에 있는 모든 jpg파일들을 각각의 pdf로 변환시켜주는 것이다.

 

위 코드를 작성할 때 본인이 약간? 신경쓴 부분이라면 PDDocument를 생성해주고 doc.close()로 닫아주는 것이다.

1개의 pdf를 만드는 것이 아니라 여러개의 pdf를 생성하는 것이기 때문에 새로운 pdf를 만드는 시점에 잘 생성해주고

1개의 pdf가 다 만들어졌다면 잘 닫아줘야하는 것이다.

 

알맞은 곳에서 생성과 닫음을 잘 해주지 못하면 '어린왕자'라는 책 안에 '홍길동'의 내용이 섞이는 문제가 발생한다.

 

 

본인이 변환해야할 pdf는 대략 2000권 정도이니... 돌려놓고 퇴근이나 해야겠다...

 

 

* 2022-10-01

그냥 버리기 아까워서 간단히 jpg 파일들을 pdf로 바꿔주는 사이트를 만들어 호스팅 해보았습니다.

 

 

http://www.jpgtopdf.store

 

JPGTOPDF

 

www.jpgtopdf.store

 

728x90
반응형

'Web' 카테고리의 다른 글

cmd에서 JAVA 컴파일 및 class파일 실행(라이브러리 함께)  (0) 2022.08.03
JAVA 설치 및 환경변수 설정  (0) 2022.08.03
== vs equals  (0) 2022.07.28
JAVA 오늘 날짜 구하기  (0) 2022.07.28
Maven 과 Gradle  (0) 2022.07.27