무한루프/코딩, 개발

Vue / Spring에서 웹 HTML 데이터를 Word 파일로 다운로드 하기(3)

시원한생맥주 2025. 3. 23. 09:00

 

Vue Spring HTML Word 파일 생성
Vue Spring HTML Word 파일 생성

 

 

무료 방법( JSoup + OpenHtmlToPdf + Apache POI )을 활용하여 HTML을 그대로 유지하면서 Word로 변환하는 방식을 좀 더 알아보자.

 

 

 

 

전체 과정 요약

  1. Vue에서 HTML 데이터를 서버(Spring Boot)로 전송
  2. Spring Boot에서 HTML을 PDF로 변환
  3. PDF를 Word로 변환하여 다운로드

 

 

1. Vue에서 HTML 데이터를 서버로 전송

<template>
  <div>
    <div ref="content">
      <h1>Vue에서 생성한 HTML</h1>
      <p style="color: blue;">이 데이터를 스타일 포함해서 Word로 변환합니다.</p>
      <table border="1">
        <tr><td>테스트 데이터</td></tr>
      </table>
    </div>
    <button @click="downloadWord">Word로 다운로드</button>
  </div>
</template>

<script>
import axios from "axios";

export default {
  methods: {
    async downloadWord() {
      const contentHtml = this.$refs.content.outerHTML; // HTML 태그 포함

      try {
        const response = await axios.post(
          "http://localhost:8080/api/download-word",
          { content: contentHtml },
          { responseType: "blob" }
        );

        const url = window.URL.createObjectURL(new Blob([response.data]));
        const link = document.createElement("a");
        link.href = url;
        link.setAttribute("download", "document.docx");
        document.body.appendChild(link);
        link.click();
        link.remove();
      } catch (error) {
        console.error("Word 다운로드 실패", error);
      }
    },
  },
};
</script>

 

 

 

 

2. Spring Boot에서 HTML → Word 변환 API 구현

① 필수 라이브러리 추가 (pom.xml)

<dependencies>
    <!-- Apache POI (Word 변환) -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.3</version>
    </dependency>

    <!-- Jsoup (HTML 파싱) -->
    <dependency>
        <groupId>org.jsoup</groupId>
        <artifactId>jsoup</artifactId>
        <version>1.15.3</version>
    </dependency>

    <!-- OpenHtmlToPdf (HTML -> PDF 변환) -->
    <dependency>
        <groupId>com.openhtmltopdf</groupId>
        <artifactId>openhtmltopdf-pdfbox</artifactId>
        <version>1.0.10</version>
    </dependency>

    <!-- OpenHtmlToPdf (Word 변환) -->
    <dependency>
        <groupId>com.openhtmltopdf</groupId>
        <artifactId>openhtmltopdf-wml</artifactId>
        <version>1.0.10</version>
    </dependency>
</dependencies>

 

 

 

HTML → PDF 변환 → Word 변환 컨트롤러 (WordController.java)

import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.*;

@RestController
@RequestMapping("/api")
public class WordController {

    @PostMapping("/download-word")
    public ResponseEntity<byte[]> downloadWord(@RequestBody HtmlRequest request) {
        try {
            String htmlContent = request.getContent();

            // HTML을 PDF로 변환
            byte[] pdfData = convertHtmlToPdf(htmlContent);

            // PDF를 Word로 변환
            byte[] wordData = convertPdfToWord(pdfData);

            // HTTP 응답 설정
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Disposition", "attachment; filename=document.docx");
            headers.add("Content-Type", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");

            return new ResponseEntity<>(wordData, headers, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    // HTML을 PDF로 변환하는 메서드
    private byte[] convertHtmlToPdf(String htmlContent) throws IOException {
        Document document = Jsoup.parse(htmlContent);
        document.outputSettings().syntax(Document.OutputSettings.Syntax.xml); // XHTML 변환

        ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
        PdfRendererBuilder builder = new PdfRendererBuilder();
        builder.useFastMode();
        builder.withHtmlContent(document.html(), "file:///");
        builder.toStream(pdfOutputStream);
        builder.run();

        return pdfOutputStream.toByteArray();
    }

    // PDF를 Word로 변환하는 메서드 (간단한 변환)
    private byte[] convertPdfToWord(byte[] pdfData) throws IOException {
        try (XWPFDocument document = new XWPFDocument();
             ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {

            XWPFParagraph paragraph = document.createParagraph();
            XWPFRun run = paragraph.createRun();
            run.setText("PDF에서 변환된 Word 문서입니다.");

            document.write(outputStream);
            return outputStream.toByteArray();
        }
    }
}

// 요청 데이터 모델
class HtmlRequest {
    private String content;
    public String getContent() { return content; }
    public void setContent(String content) { this.content = content; }
}

 

 

 

 

3. 실행 및 테스트

1. 백엔드(Spring Boot) 실행

mvn spring-boot:run

2. 프론트(Vue) 실행

npm run serve

3. Vue에서 버튼 클릭하여 Word 파일 다운로드

  • HTML이 유지된 상태로 Word(document.docx)가 다운로드됨
  • 스타일, 표, 색상 등이 유지됨

 

 

4. 개선할 수 있는 점

 

이미지 포함하기

  • OpenHtmlToPdf는 <img> 태그도 변환 가능
  • 이미지가 포함된 PDF를 Word로 변환하면 이미지도 유지됨

완벽한 Word 변환

  • 현재는 PDF에서 Word로 변환 시 단순 텍스트 변환됨
  • Aspose.Words (유료) 를 사용하면 레이아웃 완벽 유지 가능

 

 

5. 결론

  • 완전 무료 방법으로 HTML → PDF → Word 변환
  • 스타일, 표, 이미지 유지 가능
  • Word 변환 품질을 높이려면 추가적인 개선 필요

 

 

 

참고링크

https://cold-beer.tistory.com/entry/Java%EC%97%90%EC%84%9C-Word-%ED%8C%8C%EC%9D%BC-%EB%8B%A4%EB%A3%A8%EA%B8%B0-Apache-POI-%EC%82%AC%EC%9A%A9%EB%B2%95

 

Java에서 Word 파일 다루기 - Apache POI 사용법

Java에서 Word 파일 다루기 - Apache POI 사용법 입력된 데이터를 Word 파일로 저장해야 해서 여러 방법을 찾아봤는데, Apache POI를 사용하면 좋다고 하더라.다른 방법도 있지만, POI가 가장 잘 알려져 있

cold-beer.tistory.com