编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

Java实现Word打印效果(java打印模版)

wxchong 2024-07-06 01:08:50 开源技术 18 ℃ 0 评论

实现思路:先利用word做出模板,转成程序可进行操作的xml文件,再利用freemarker处理成带数据的真实文件,然后再转成pdf,前端页面中直接预览打印。



用到的第三方资源:

1.aspose-words-15.8.0-jdk16.jar

2.aspose-cells-8.5.2.jar

3.freemarker.jar

本例子支持生成文件及数据流,因为一般情况下生成word和转换为pdf是同时进行的,所以这里推荐采用了流的形式进行转换及展示,主要代码如下:

因为aspose是收费的,所以这里有一个破解版,就是在项目中放一个License.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<License>
<Data>
<Products>
<Product>Aspose.Total for Java</Product>
<Product>Aspose.Words for Java</Product>
</Products>
<EditionType>Enterprise</EditionType>
<SubscriptionExpiry>20991231</SubscriptionExpiry>
<LicenseExpiry>20991231</LicenseExpiry>
<SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
</Data>
<Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
</License>

相应的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.5.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring-demo2</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/freemarker/freemarker -->
		<dependency>
		    <groupId>freemarker</groupId>
		    <artifactId>freemarker</artifactId>
		    <version>2.3.9</version>
		</dependency>
		<dependency>
        	<groupId>com.google.zxing</groupId>
        	<artifactId>core</artifactId>
        	<version>3.3.0</version>
    	</dependency>
    	<dependency>
        	<groupId>com.google.zxing</groupId>
        	<artifactId>javase</artifactId>
        	<version>3.3.0</version>
    	</dependency>
		        
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

TestController.java 其中word方法只支持生成word文件,word2pdf方法是已文件的形式生成pdf,word2pdf_byte方法是已流的形式生成pdf

package com.example.demo.controller;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.example.demo.util.FreeMarkerUtil;
import com.example.demo.util.PdfUtil;
import com.example.demo.util.QRCodeGenerator;
import com.google.zxing.WriterException;

@Controller
public class TestController {
	
	@RequestMapping("/word")
	public void word(HttpServletResponse response) throws IOException{
		String imagestr = null;
		try {
			imagestr = QRCodeGenerator.getQRCodeImageStr("test", 360, 360);
		} catch (WriterException e) {
			System.out.println("Could not generate QR Code, WriterException :: " + e.getMessage());
			e.printStackTrace();
		} 
		
		Map<String, Object> map = new HashMap<String, Object>();
        map.put("qrCodeImage", imagestr);
        map.put("title1", "标题一");
        map.put("title2", "标题二");
        map.put("title3", "标题三");
        map.put("title4", "标题四");
        map.put("title5", "标题五");
        map.put("value1", "描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1");
        map.put("value2", "描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2");
        map.put("value3", "描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3");
        map.put("value4", "描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4");
        map.put("value5", "描述5描述5描述5描述5描述5描述5描述5描述5描述5描述5描述5描述5描述5");
      //下载word文档
        File file = null;
        InputStream fin = null;
        ServletOutputStream out = null;
        try {
            // 调用工具类WordGenerator的createDoc方法生成Word文档
            file = FreeMarkerUtil.createDoc(map, "qrCode");
            fin = new FileInputStream(file);
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            // 设置浏览器以下载的方式处理该文件默认名为resume.doc
            response.addHeader("Content-Disposition","attachment;filename="+ UUID.randomUUID() +".doc");
            out = response.getOutputStream();
            byte[] buffer = new byte[512]; // 缓冲区
            int bytesToRead = -1;
            // 通过循环将读入的Word文件的内容输出到浏览器中
            while ((bytesToRead = fin.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }
        } finally {
            if (fin != null)
                fin.close();
            if (out != null)
                out.close();
            if (file != null)
                file.delete(); // 删除临时文件
        }
	}
	
	@RequestMapping("/word2pdf")
	@ResponseBody
	public String word2pdf(HttpServletResponse response) throws IOException{
		String imagestr = null;
		try {
			imagestr = QRCodeGenerator.getQRCodeImageStr("test", 360, 360);
		} catch (WriterException e) {
			System.out.println("Could not generate QR Code, WriterException :: " + e.getMessage());
			e.printStackTrace();
		} 
		
		Map<String, Object> map = new HashMap<String, Object>();
        map.put("qrCodeImage", imagestr);
        map.put("title1", "标题一");
        map.put("title2", "标题二");
        map.put("title3", "标题三");
        map.put("title4", "标题四");
        map.put("title5", "标题五");
        map.put("value1", "描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1");
        map.put("value2", "描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2");
        map.put("value3", "描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3");
        map.put("value4", "描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4");
        map.put("value5", "描述5描述5描述5描述5描述5描述5描述5描述5描述5描述5描述5描述5描述5");
      
        File file = FreeMarkerUtil.createDoc(map, "qrCode");
        System.out.println(file.getAbsolutePath());
        PdfUtil.doc2pdf(file.getAbsolutePath(), "d:\\test.pdf");
        return "success";
	}
	
	@RequestMapping("/word2pdf_byte")
	public void word2pdf_byte(HttpServletResponse response) throws IOException{
		String imagestr = null;
		try {
			imagestr = QRCodeGenerator.getQRCodeImageStr("test", 360, 360);
		} catch (WriterException e) {
			System.out.println("Could not generate QR Code, WriterException :: " + e.getMessage());
			e.printStackTrace();
		} 
		
		Map<String, Object> map = new HashMap<String, Object>();
        map.put("qrCodeImage", imagestr);
        map.put("title1", "标题一");
        map.put("title2", "标题二");
        map.put("title3", "标题三");
        map.put("title4", "标题四");
        map.put("title5", "标题五");
        map.put("value1", "描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1描述1");
        map.put("value2", "描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2描述2");
        map.put("value3", "描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3描述3");
        map.put("value4", "描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4描述4");
        map.put("value5", "描述5描述5描述5描述5描述5描述5描述5描述5描述5描述5描述5描述5描述5");
      
        byte[] bytes = FreeMarkerUtil.createDocByte(map, "qrCode");
        ByteArrayOutputStream outputStream = PdfUtil.docByte2pdfByte(bytes);
        response.getOutputStream().write(outputStream.toByteArray());
//        File file = FreeMarkerUtil.createDoc(map, "qrCode");
//        System.out.println(file.getAbsolutePath());
//        PdfUtil.doc2pdf(file.getAbsolutePath(), "d:\\test.pdf");
	}

}

FreeMarkerUtil.java 这里demo采用的是springboot框架,所以将静态资源放在/static/tpl/文件夹中

package com.example.demo.util;

import freemarker.template.Configuration;
import freemarker.template.Template;
import sun.misc.BASE64Encoder;
 
import java.io.*;
import java.util.HashMap;
import java.util.Map;
 
public class FreeMarkerUtil {
    private static Configuration configuration = null;
    private static HashMap<String, Template> allTemplates = null;
    static {
        configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
        configuration.setClassForTemplateLoading(FreeMarkerUtil.class,"/static/tpl/");//模板ftl文件在templates下面
        /*
         * allTemplates = new HashMap<>();
         */
        allTemplates = new HashMap<String, Template>();
        try {
            allTemplates.put("qrCode", configuration.getTemplate("qrCode.ftl"));
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
 
 
    public static File createDoc(Map<?, ?> dataMap, String type) {
        String name = "temp" + (int) (Math.random() * 100000) + ".doc";
        File f = new File(name);
//        Template t = allTemplates.get(type);
        try {
        	Template t = configuration.getTemplate(type + ".ftl");
            // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
            Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
            t.process(dataMap, w);
            w.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
        return f;
    }
    
    public static byte[] createDocByte(Map<?, ?> dataMap, String type) {
//        Template t = allTemplates.get(type);
    	ByteArrayOutputStream byteArrayOutputStream = null;
        try {
        	Template t = configuration.getTemplate(type + ".ftl");
            // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
        	byteArrayOutputStream = new ByteArrayOutputStream();
            Writer w = new OutputStreamWriter(byteArrayOutputStream);
            t.process(dataMap, w);
            w.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
        return byteArrayOutputStream.toByteArray();
    }
}

PdfUtil.java: 其中license.xml文件可以根据实际的项目配置到自定义的路径

package com.example.demo.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.aspose.cells.Workbook;
import com.aspose.words.Document;
import com.aspose.words.License;

/**
* Word或Excel 转Pdf 帮助类
* @author lenovo
* 备注:需要引入 aspose-words-15.8.0-jdk16.jar / aspose-cells-8.5.2.jar
*/
public class PdfUtil {

    private static boolean getLicense() {
        boolean result = false;
       try {
           InputStream is = PdfUtil.class.getClassLoader().getResourceAsStream("license.xml"); // license.xml应放在..\WebRoot\WEB-INF\classes路径下
           License aposeLic = new License();
          aposeLic.setLicense(is);
          result = true;
       } catch (Exception e) {
         e.printStackTrace();
      }
     return result;
   }

   /**
  * @param wordPath 需要被转换的word全路径带文件名
  * @param pdfPath 转换之后pdf的全路径带文件名
  */
  public static void doc2pdf(String wordPath, String pdfPath) {
     if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
        return;
     }
    try {
        long old = System.currentTimeMillis();
        File file = new File(pdfPath); //新建一个pdf文档
        FileOutputStream os = new FileOutputStream(file);
        Document doc = new Document(wordPath); //Address是将要被转化的word文档
        doc.save(os, com.aspose.words.SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
        long now = System.currentTimeMillis();
        os.close();
        System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒"); //转化用时
        } catch (Exception e) {
            e.printStackTrace();
        }
     }
  
  public static void docByte2pdf(byte[] bytesWord, String pdfPath) {
     if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
        return;
     }
     ByteArrayInputStream byteArrayInputStream = null;
    try {
        long old = System.currentTimeMillis();
        File file = new File(pdfPath); //新建一个pdf文档
        FileOutputStream os = new FileOutputStream(file);
        byteArrayInputStream = new ByteArrayInputStream(bytesWord);
        Document doc = new Document(byteArrayInputStream);
        doc.save(os, com.aspose.words.SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
        long now = System.currentTimeMillis();
        os.close();
        System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒"); //转化用时
        } catch (Exception e) {
            e.printStackTrace();
        }
  }

  
  public static ByteArrayOutputStream docByte2pdfByte(byte[] bytesWord) {
	     if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
	        return null;
	     }
	     ByteArrayInputStream byteArrayInputStream = null;
	     ByteArrayOutputStream byteArrayOutputStream = null;
	    try {
	        long old = System.currentTimeMillis();
	        byteArrayOutputStream = new ByteArrayOutputStream();
	        byteArrayInputStream = new ByteArrayInputStream(bytesWord);
	        Document doc = new Document(byteArrayInputStream);
	        doc.save(byteArrayOutputStream, com.aspose.words.SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
	        long now = System.currentTimeMillis();
	        byteArrayOutputStream.close();
	        byteArrayInputStream.close();
	        System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒"); //转化用时
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	    return byteArrayOutputStream;
	  }
   /**
   * @param excelPath 需要被转换的excel全路径带文件名
   * @param pdfPath 转换之后pdf的全路径带文件名
   */
    public static void excel2pdf(String excelPath, String pdfPath) {
        if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
        return;
       }
      try {
         long old = System.currentTimeMillis();
        Workbook wb = new Workbook(excelPath);// 原始excel路径
        FileOutputStream fileOS = new FileOutputStream(new File(pdfPath));
        wb.save(fileOS, com.aspose.cells.SaveFormat.PDF);
        fileOS.close();
        long now = System.currentTimeMillis();
           System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒"); //转化用时
        } catch (Exception e) {
          e.printStackTrace();
       }
     }

      public static void main(String[] args) {

          //word 和excel 转为pdf
          String filePaths="D:/logs/Java多线程大合集.doc";
          String fileName="zsqexcel78";
         String pdfPath="D:/logs/"+fileName+".pdf";
         //doc2pdf(filePaths, pdfPath);//filePaths需要转换的文件位置 pdfPath为存储位置
         String excel2pdf="D:/logs/excelToPdf.xlsx";
         excel2pdf(excel2pdf,pdfPath);
      }
 }

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表