原文: http://zetcode.com/articles/javaservletpdf/

Java servlet PDF 教程展示了如何从 Java servlet 返回 PDF 数据。 我们使用 iText 库处理 PDF。 该 Web 应用已部署在 Tomcat 服务器上。

PDF 格式

便携式文档格式(PDF)是用于以独立于应用软件,硬件和操作系统的方式呈现文档的文件格式。 PDF 由 Adobe 发明,现在是国际标准化组织(ISO)维护的开放标准。

Java Servlet

Servlet 是 Java 类,可响应特定类型的网络请求-最常见的是 HTTP 请求。 Java servlet 用于创建 Web 应用。 它们在 servlet 容器(例如 Tomcat 或 Jetty)中运行。 现代 Java Web 开发使用在 servlet 之上构建的框架。

iText

iText 是一个开放源代码库,用于在 Java 中创建和处理 PDF 文件。

Java Servlet PDF 应用

以下 Web 应用使用 Java Servlet 将 PDF 文件发送到客户端。 它从对象列表生成 PDF。

  1. $ tree
  2. .
  3. ├── pom.xml
  4. └── src
  5. ├── main
  6. ├── java
  7. └── com
  8. └── zetcode
  9. ├── bean
  10. └── City.java
  11. ├── service
  12. └── CityService.java
  13. ├── util
  14. └── GeneratePdf.java
  15. └── web
  16. └── MyServlet.java
  17. └── webapp
  18. ├── index.html
  19. ├── META-INF
  20. └── context.xml
  21. └── WEB-INF
  22. └── test
  23. └── java

这是项目结构。

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  5. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6. <modelVersion>4.0.0</modelVersion>
  7. <groupId>com.zetcode</groupId>
  8. <artifactId>JavaServletPDF</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>war</packaging>
  11. <name>JavaServletPDF</name>
  12. <properties>
  13. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  14. <maven.compiler.source>1.8</maven.compiler.source>
  15. <maven.compiler.target>1.8</maven.compiler.target>
  16. </properties>
  17. <dependencies>
  18. <dependency>
  19. <groupId>javax.servlet</groupId>
  20. <artifactId>javax.servlet-api</artifactId>
  21. <version>3.1.0</version>
  22. <scope>provided</scope>
  23. </dependency>
  24. <dependency>
  25. <groupId>com.lowagie</groupId>
  26. <artifactId>itext</artifactId>
  27. <version>4.2.2</version>
  28. </dependency>
  29. </dependencies>
  30. <build>
  31. <plugins>
  32. <plugin>
  33. <groupId>org.apache.maven.plugins</groupId>
  34. <artifactId>maven-war-plugin</artifactId>
  35. <version>2.3</version>
  36. <configuration>
  37. <failOnMissingWebXml>false</failOnMissingWebXml>
  38. </configuration>
  39. </plugin>
  40. </plugins>
  41. </build>
  42. </project>

这是 Maven POM 文件。 我们有两个工件:用于 Java 的 servlet 的javax.servlet-api和用于 PDF 生成的itextmaven-war-plugin负责收集 Web 应用的所有工件依赖项,类和资源,并将它们打包到 Web 应用存档(WAR)中。

context.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Context path="/JavaServletPdf"/>

在 Tomcat context.xml文件中,我们定义了上下文路径。 它是 Web 应用的名称。

City.java

  1. package com.zetcode.bean;
  2. public class City {
  3. private Long id;
  4. private String name;
  5. private int population;
  6. public City() {
  7. }
  8. public City(Long id, String name, int population) {
  9. this.id = id;
  10. this.name = name;
  11. this.population = population;
  12. }
  13. public Long getId() {
  14. return id;
  15. }
  16. public void setId(Long id) {
  17. this.id = id;
  18. }
  19. public String getName() {
  20. return name;
  21. }
  22. public void setName(String name) {
  23. this.name = name;
  24. }
  25. public int getPopulation() {
  26. return population;
  27. }
  28. public void setPopulation(int population) {
  29. this.population = population;
  30. }
  31. @Override
  32. public String toString() {
  33. return "City{" + "id=" + id + ", name=" + name +
  34. ", population=" + population + '}';
  35. }
  36. }

这是City bean。 它具有三个属性:idnamepopulation

MyServlet.java

  1. package com.zetcode.web;
  2. import com.zetcode.bean.City;
  3. import com.zetcode.service.CityService;
  4. import com.zetcode.util.GeneratePdf;
  5. import java.io.ByteArrayOutputStream;
  6. import java.io.IOException;
  7. import java.util.List;
  8. import javax.servlet.ServletException;
  9. import javax.servlet.ServletOutputStream;
  10. import javax.servlet.annotation.WebServlet;
  11. import javax.servlet.http.HttpServlet;
  12. import javax.servlet.http.HttpServletRequest;
  13. import javax.servlet.http.HttpServletResponse;
  14. @WebServlet(name = "MyServlet", urlPatterns = {"/MyServlet"})
  15. public class MyServlet extends HttpServlet {
  16. @Override
  17. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  18. throws ServletException, IOException {
  19. response.setContentType("application/pdf;charset=UTF-8");
  20. response.addHeader("Content-Disposition", "inline; filename=" + "cities.pdf");
  21. ServletOutputStream out = response.getOutputStream();
  22. List<City> cities = CityService.getCities();
  23. ByteArrayOutputStream baos = GeneratePdf.getPdfFile(cities);
  24. baos.writeTo(out);
  25. }
  26. }

这是MyServlet servlet。 它从服务类检索数据,从数据生成 PDF 文件,然后将 PDF 文件返回给客户端。

  1. response.setContentType("application/pdf;charset=UTF-8");

我们将响应对象的内容类型设置为application/pdf

  1. response.addHeader("Content-Disposition", "inline; filename=" + "cities.pdf");

Content-Disposition响应标头指示内容应在浏览器中显示为inline,即作为 Web 页面或 Web 页面的一部分,或作为attachment在本地下载和保存。 。 可选的filename伪指令指定传输文件的名称。

  1. ServletOutputStream out = response.getOutputStream();

我们从响应对象获得ServletOutputStream

  1. List<City> cities = CityService.getCities();

CityService中,我们可以获得城市列表。

  1. List<City> cities = CityService.getCities();

CityService中,我们可以获得城市列表。

  1. ByteArrayOutputStream baos = GeneratePdf.getPdfFile(cities);
  2. baos.writeTo(out);

我们根据数据生成 PDF 文件,并将返回的ByteArrayOutputStream写入ServletOutputStream

CityService.java

  1. package com.zetcode.service;
  2. import com.zetcode.bean.City;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. public class CityService {
  6. public static List<City> getCities() {
  7. List<City> cities = new ArrayList<>();
  8. cities.add(new City(1L, "Bratislava", 432000));
  9. cities.add(new City(2L, "Budapest", 1759000));
  10. cities.add(new City(3L, "Prague", 1280000));
  11. cities.add(new City(4L, "Warsaw", 1748000));
  12. cities.add(new City(5L, "Los Angeles", 3971000));
  13. cities.add(new City(6L, "New York", 8550000));
  14. cities.add(new City(7L, "Edinburgh", 464000));
  15. cities.add(new City(8L, "Berlin", 3671000));
  16. return cities;
  17. }
  18. }

CityServicegetCities()方法返回城市对象的列表。

GeneratePdf.java

  1. package com.zetcode.util;
  2. import com.itextpdf.text.Document;
  3. import com.itextpdf.text.DocumentException;
  4. import com.itextpdf.text.Element;
  5. import com.itextpdf.text.Font;
  6. import com.itextpdf.text.FontFactory;
  7. import com.itextpdf.text.Phrase;
  8. import com.itextpdf.text.pdf.PdfPCell;
  9. import com.itextpdf.text.pdf.PdfPTable;
  10. import com.itextpdf.text.pdf.PdfWriter;
  11. import com.zetcode.bean.City;
  12. import java.io.ByteArrayOutputStream;
  13. import java.util.List;
  14. import java.util.logging.Level;
  15. import java.util.logging.Logger;
  16. public class GeneratePdf {
  17. public static ByteArrayOutputStream getPdfFile(List<City> cities) {
  18. Document document = new Document();
  19. ByteArrayOutputStream bout = new ByteArrayOutputStream();
  20. try {
  21. PdfPTable table = new PdfPTable(3);
  22. table.setWidthPercentage(60);
  23. table.setWidths(new int[]{1, 3, 3});
  24. Font headFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD);
  25. PdfPCell hcell;
  26. hcell = new PdfPCell(new Phrase("Id", headFont));
  27. hcell.setHorizontalAlignment(Element.ALIGN_CENTER);
  28. table.addCell(hcell);
  29. hcell = new PdfPCell(new Phrase("Name", headFont));
  30. hcell.setHorizontalAlignment(Element.ALIGN_CENTER);
  31. table.addCell(hcell);
  32. hcell = new PdfPCell(new Phrase("Population", headFont));
  33. hcell.setHorizontalAlignment(Element.ALIGN_CENTER);
  34. table.addCell(hcell);
  35. for (City city : cities) {
  36. PdfPCell cell;
  37. cell = new PdfPCell(new Phrase(city.getId().toString()));
  38. cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
  39. cell.setHorizontalAlignment(Element.ALIGN_CENTER);
  40. table.addCell(cell);
  41. cell = new PdfPCell(new Phrase(city.getName()));
  42. cell.setPaddingLeft(5);
  43. cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
  44. cell.setHorizontalAlignment(Element.ALIGN_LEFT);
  45. table.addCell(cell);
  46. cell = new PdfPCell(new Phrase(String.valueOf(city.getPopulation())));
  47. cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
  48. cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
  49. cell.setPaddingRight(5);
  50. table.addCell(cell);
  51. }
  52. PdfWriter.getInstance(document, bout);
  53. document.open();
  54. document.add(table);
  55. document.close();
  56. } catch (DocumentException ex) {
  57. Logger.getLogger(GeneratePdf.class.getName()).log(Level.SEVERE, null, ex);
  58. }
  59. return bout;
  60. }
  61. }

GeneratePdf根据提供的数据创建 PDF 文件。

  1. ByteArrayOutputStream bout = new ByteArrayOutputStream();

数据将被写入ByteArrayOutputStreamByteArrayOutputStream实现了一个输出流,其中数据被写入字节数组。

  1. PdfPTable table = new PdfPTable(3);

我们将数据放在表格中; 为此,我们有PdfPTable类。 该表具有三列:ID,名称和人口。

  1. Font headFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD);

我们使用粗体 Helvetica 字体作为表标题。

  1. PdfPCell hcell;
  2. hcell = new PdfPCell(new Phrase("Id", headFont));
  3. hcell.setHorizontalAlignment(Element.ALIGN_CENTER);
  4. table.addCell(hcell);

数据放置在表单元格内,由PdfPCell表示。 setHorizontalAlignment()方法使文本水平对齐。

  1. PdfWriter.getInstance(document, bout);

使用PdfWriter,将文档写入ByteArrayOutputStream

  1. document.open();
  2. document.add(table);

该表将插入到 PDF 文档中。

  1. document.close();

为了将数据写入ByteArrayOutputStream,必须关闭文档。

  1. return bout;

最后,数据返回为ByteArrayOutputStream

在本教程中,我们从 Java servlet 发送了 PDF 数据。

您可能也对以下相关教程感兴趣: Java RequestDispatcherJava Servlet 图表教程从 Java Servlet 提供纯文本Java Servlet 检查框教程Java servlet 图像教程Java Servlet HTTP 标头Java 教程