Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Generating Word Documents in Spring Boot with POI-TL and Previewing in Vue via vue-office

Tech Jun 8 1

Backend: Java Service Integration

Add the POI-TL library to your Maven pom.xml:

<dependency>
    <groupId>com.deepoove</groupId>
    <artifactId>poi-tl</artifactId>
    <version>1.7.3</version>
</dependency>

Create a placeholder-based Word template (.docx) and place it under the resources/templates directory, for example payment_cover.docx.

Implement a service method that populates the template and streams it to the HTTP response:

import com.deepoove.poi.XWPFTemplate;
import org.springframework.core.io.ClassPathResource;

// inside a controller or service
public void exportPaymentCover(HttpServletResponse response) throws Exception {
    String templateLocation = "templates/payment_cover.docx";
    ClassPathResource resource = new ClassPathResource(templateLocation);

    Map<String, Object> data = new HashMap<>();
    data.put("contractor", "Acme Construction Co.");
    data.put("paymentPhase", "Phase II - North Zone");
    data.put("preparedBy", "Global Supplies Ltd.");
    data.put("siteOffice", "SafeBuild Engineering Consultants");
    data.put("headOffice", "Highway Project Management Co.");
    data.put("date", "2024-08-15");

    response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
    response.setHeader("Content-Disposition", "attachment; filename=payment_cover.docx");

    try (InputStream templateStream = resource.getInputStream();
         OutputStream out = response.getOutputStream()) {

        XWPFTemplate template = XWPFTemplate.compile(templateStream).render(data);
        template.write(out);
        out.flush();
    }
}

Frontend: Vue Integration

Install the @vue-office/docx package:

npm install --save @vue-office/docx

dispatch the output as a Blob from the backend API call, convert it to an object URL, and04 render it with the <vue-office-docx> component.

Template section:

<template>
  <div>
    <vue-office-docx 
      v-if="documentUrl" 
      :src="documentUrl" 
      @rendered="handleRendered" 
      id="docPreview" 
    />
    <button @click="printDocument">Print</button>
    <button @click="downloadDocument">Download</button>
  </div>
</template>

Script setup:

import { ref } from 'vue';
import VueOfficeDocx from '@vue-office/docx';
import '@vue-office/docx/lib/index.css';
import { saveAs } from 'file-saver';

export default {
  components: { VueOfficeDocx },
  setup() {
    const documentUrl = ref(null);
    const blobData = ref(null);
    const fileName = ref('document.docx');

    // Simulated fetch: replace with real API call
    const fetchDocument = async () => {
      const response = await fetch('/api/export/paymentCover');
      const arrayBuffer = await response.arrayBuffer();
      const blob = new Blob([arrayBuffer], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
      blobData.value = blob;
      documentUrl.value = window.URL.createObjectURL(blob);
    };

    const handleRendered = () => {
      console.log('Document preview rendered successfully');
    };

    const printDocument = () => {
      const container = document.getElementById('docPreview');
      if (container) {
        const wrapper = container.querySelector('.docx-wrapper');
        if (wrapper) {
          // optional: use a print plugin, e.g., vue-print-nb
          this.$print(wrapper);
        }
      }
    };

    const downloadDocument = () => {
      if (blobData.value) {
        saveAs(blobData.value, fileName.value);
      }
    };

    return {
      documentUrl,
      handleRendered,
      printDocument,
      downloadDocument,
      fetchDocument
    };
  },
  mounted() {
    this.fetchDocument();
  }
};

The vue-office-docx component handles rendering the docx file directly in the browser. The blob URL is passed as the src prop. After the document is rendered, you can integrate print functionality by targeting the internal wrapper element.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

SBUS Signal Analysis and Communication Implementation Using STM32 with Fus Remote Controller

Overview In a recent project, I utilized the SBUS protocol with the Fus remote controller to control a vehicle's basic operations, including movement, lights, and mode switching. This article is aimed...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.