목차
3.页眉页脚
如宋体:font-family:SimSun;正确
font-family:宋体;则错误,竟然unicode也不行。
5.其他
웹 프론트엔드 HTML 튜토리얼 使用iText生成PDF_html/css_WEB-ITnose

使用iText生成PDF_html/css_WEB-ITnose

Jun 21, 2016 am 08:52 AM

iText的更新变化很大,早期版本在PDF样式上可能会有瑕疵,所有我使用的最新的5.5.6包

1.添加Maven依赖

itext核心包 和xmlworder字体包

<dependency>      <groupId>com.itextpdf</groupId>     <artifactId>itextpdf</artifactId>     <version>5.5.6</version></dependency>
로그인 후 복사
<dependency>   <groupId>com.itextpdf.tool</groupId>   <artifactId>xmlworker</artifactId>   <version>5.5.6</version></dependency>
로그인 후 복사

2. 直接生成pdf的方式,非常简单,用文字创建段落等即可,设置好字体、间距、对齐方式等等即可,弄个Hello World 的例子。

package com.thunisoft.demo;  import java.io.FileOutputStream;  import com.itextpdf.text.Document;  import com.itextpdf.text.Font;  import com.itextpdf.text.FontFactoryImp;  import com.itextpdf.text.PageSize;  import com.itextpdf.text.Paragraph;  import com.itextpdf.text.pdf.BaseFont;  import com.itextpdf.text.pdf.PdfPHeaderCell;  import com.itextpdf.text.pdf.PdfPTable;  import com.itextpdf.text.pdf.PdfWriter;     /**  * 创建一个简单pdf文档,文字、表格  *  * @author zhangwd  * @version 1.0  *  */  public class PdfDemo_1 {      private static void create() throws Exception {          // 创建一个文档(默认大小A4,边距36, 36, 36, 36)          Document document = new Document();          // 设置文档大小          document.setPageSize(PageSize.A4);          // 设置边距,单位都是像素,换算大约1厘米=28.33像素          document.setMargins(50, 50, 50, 50);             // 创建writer,通过writer将文档写入磁盘          PdfWriter writer = PdfWriter.getInstance(document,newFileOutputStream("c:/demo.1.pdf"));             // demo          String title = "凉州词";          String content = "黄河远上白云间,一片孤城万仞山。羌笛何须怨杨柳,春风不度玉门关。";             // 定义字体          FontFactoryImp ffi = new FontFactoryImp();          // 注册全部默认字体目录,windows会自动找fonts文件夹的,返回值为注册到了多少字体          ffi.registerDirectories();          // 获取字体,其实不用这么麻烦,后面有简单方法          Font font = ffi.getFont("宋体",BaseFont.IDENTITY_H,BaseFont.EMBEDDED, 12, Font.UNDEFINED, null);             // 打开文档,只有打开后才能往里面加东西          document.open();             // 设置作者          document.addAuthor("王之涣");          // 设置创建者          document.addCreator("王之涣");          // 设置主题          document.addSubject("测试");          // 设置标题          document.addTitle("凉州词");             // 增加一个段落          document.add(new Paragraph(title, font));          document.add(new Paragraph(content, font));          document.add(new Paragraph("\n\r", font));             // 创建表格,5列的表格          PdfPTable table = new PdfPTable(4);          table.setTotalWidth(PageSize.A4.getWidth()- 100);          table.setLockedWidth(true);          // 创建头          PdfPHeaderCell header = new PdfPHeaderCell();          header.addElement(new Paragraph(title, font));          header.setColspan(4);          table.addCell(header);          // 添加内容          table.addCell(new Paragraph("黄河远上白云间",font));          table.addCell(new Paragraph("一片孤城万仞山",font));          table.addCell(new Paragraph("羌笛何须怨杨柳",font));          table.addCell(new Paragraph("春风不度玉门关",font));             document.add(table);          // 关闭文档,才能输出          document.close();          writer.close();     }        public static void main(String[] args) throws Exception {          create();     }  }
로그인 후 복사

3.字体

我们项目文书字体比较特殊,比如用到了宋体(99%都这个吧)、华文仿宋(安装office后自带)、仿宋_GB2312等,于是就研究了一下pdf字体,网上有很多方法使用中文字体,其实5.0版以后的iText加入字体还是很方便的。

还是HelloWorld例子:

import java.io.FileOutputStream;  import com.itextpdf.text.Document;  import com.itextpdf.text.Font;  import com.itextpdf.text.FontFactoryImp;  import com.itextpdf.text.Paragraph;  import com.itextpdf.text.pdf.PdfWriter;  import com.itextpdf.tool.xml.XMLWorkerFontProvider;     /**  * 字体  *  * @author zhangwd  * @version 1.0  *  */  public class PdfDemo_2 {         public static void create() throws Exception {          Document document = new Document();          PdfWriter writer = PdfWriter.getInstance(document,new FileOutputStream("c:/demo.2.pdf"));          String title = "凉州词";          String content = "黄河远上白云间,一片孤城万仞山。羌笛何须怨杨柳,春风不度玉门关。";          document.open();          document.add(newParagraph(title, getFont("方正兰亭黑简体")));          document.add(newParagraph(content, getFont("迷你简娃娃篆")));          document.close();          writer.close();      }         private static Font getFont(String fontName) {          // xmlworker主要功能是html转pdf用的,非常好用,也是itext官方的             // 这个是xmlworker提供的获取字体方法,很方便,对中文支持很好          FontFactoryImp fp = newXMLWorkerFontProvider();          // 注册指定的字体目录,默认构造方法中会注册全部目录,我这里注册了src/font目录          fp.registerDirectory(PdfDemo_2.class.getClassLoader().getResource("font").getFile(), true);             // 最好的地方是直接支持获取中文的名字          return fp.getFont(fontName);             // 当然,最好的方法是自己继承XMLWorkerFontProvider,提供一些常用字体,简单方便      }         public static void main(String[]args) throws Exception {          create();      }  }
로그인 후 복사

xmlworker的XMLWorkerFontProvider提供了很方便的获取字体方法:

1.注册一个文件夹,里面有哪些字体都可以,比如我demo中的字体

2.使用getFont(字体名)即可获得,不过字体名从哪来的呢

3.页眉页脚

iText5中并没有之前版本HeaderFooter对象设置页眉和页脚,可以利用PdfPageEvent来完成页眉页脚的设置工作。

PdfPageEvent提供了几个pdf在创建时的事件,页眉页脚就是在每页加载完写入的。

每一页加个页码还是很简单的,但是总页码就麻烦了,iText是流模式的写入内容,只有写到最后,才能知道有多少页,那么显示总页数就麻烦了,不过麻烦不代表不可能。

其实iText仅在调用释放模板方法后才将PdfTemplate写入到OutputStream中,否则对象将一直保存在内存中,直到关闭文档。

所以我们可以在最后关闭文档前,使用PdfTemplate写入总页码。可以理解成先写个占位符,然后统一替换。

还是HelloWorld例子:

<span style="font-size:18px;">package com.thunisoft.demo;  import java.io.FileOutputStream;  import com.itextpdf.text.BaseColor;  import com.itextpdf.text.Document;  import com.itextpdf.text.Element;  import com.itextpdf.text.ExceptionConverter;  import com.itextpdf.text.Font;  import com.itextpdf.text.Image;  import com.itextpdf.text.PageSize;  import com.itextpdf.text.Paragraph;  import com.itextpdf.text.Rectangle;  import com.itextpdf.text.pdf.ColumnText;  import com.itextpdf.text.pdf.PdfContentByte;  import com.itextpdf.text.pdf.PdfPCell;  import com.itextpdf.text.pdf.PdfPTable;  import com.itextpdf.text.pdf.PdfPageEventHelper;  import com.itextpdf.text.pdf.PdfTemplate;  import com.itextpdf.text.pdf.PdfWriter;  import com.itextpdf.tool.xml.XMLWorkerFontProvider;     /**  * 页眉、页脚  *  * @author zhangwd  * @version 1.0  *  */  public class PdfDemo_3 {         public static void create() throws Exception {          Document document = newDocument(PageSize.A4, 50, 50, 50, 50);          PdfWriter writer = PdfWriter.getInstance(document,new FileOutputStream("c:/demo.3.pdf"));             // 增加页眉页脚          writer.setPageEvent(newMyHeaderFooter());             String title = "凉州词";          String content = "黄河远上白云间,一片孤城万仞山。羌笛何须怨杨柳,春风不度玉门关。";          document.open();             Font font = newXMLWorkerFontProvider().getFont("宋体");          for (int i = 0; i <100; i++) {              document.add(newParagraph(title, font));              document.add(new Paragraph(content,font));              document.add(new Paragraph("\n"));          }          document.close();          writer.close();      }         public static void main(String[]args) throws Exception {          create();      }  }     /**  * iText5中并没有之前版本HeaderFooter对象设置页眉和页脚<br>  * 不过,可以利用PdfPageEventHelper来完成页眉页脚的设置工作。<br>  * 就是在页面完成但写入内容之前触发事件,插入页眉、页脚、水印等。<br>  *  * @author zhangwd  * @version 1.0  *  */  class MyHeaderFooter extends PdfPageEventHelper {         Font font = new XMLWorkerFontProvider().getFont("宋体", 12, BaseColor.RED);         // 总页数      PdfTemplate totalPage;         // 打开文档时,创建一个总页数的模版      public void onOpenDocument(PdfWriter writer,Document document) {          PdfContentByte cb =writer.getDirectContent();          totalPage = cb.createTemplate(30, 16);      }         // 一页加载完成触发,写入页眉和页脚      public void onEndPage(PdfWriter writer, Documentdocument) {          PdfPTable table = new PdfPTable(3);          try {              table.setTotalWidth(PageSize.A4.getWidth() - 100);              table.setWidths(new int[] { 24, 24, 3});              table.setLockedWidth(true);             table.getDefaultCell().setFixedHeight(-10);             table.getDefaultCell().setBorder(Rectangle.BOTTOM);                 table.addCell(new Paragraph("我是文字", font));// 可以直接使用addCell(str),不过不能指定字体,中文无法显示             table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);              table.addCell(new Paragraph("第" + writer.getPageNumber() + "页/", font));                 // 总页数              PdfPCell cell = new PdfPCell(Image.getInstance(totalPage));              cell.setBorder(Rectangle.BOTTOM);              table.addCell(cell);                 // 将页眉写到document中,位置可以指定,指定到下面就是页脚              table.writeSelectedRows(0, -1, 50,PageSize.A4.getHeight() - 20, writer.getDirectContent());          } catch (Exception de) {              throw new ExceptionConverter(de);          }      }         // 全部完成后,将总页数的pdf模版写到指定位置      public void onCloseDocument(PdfWriter writer,Document document) {          String text = "总" + (writer.getPageNumber() - 1) + "页";          ColumnText.showTextAligned(totalPage, Element.ALIGN_LEFT, new Paragraph(text,font), 2, 2, 0);      }  }
로그인 후 복사

4.html转pdf

结果还不错,虽然可以满足我们的要求,但是比较复杂,动态创建一个个的表格和内容过于繁琐,方法太粗暴了,用户的文档内容或格式变化,就要修改程序了。

于是,我们讨论了一个比较好的方法,感谢谢国庆提供的帮助。

先创建html,然后转换成pdf,demo如下:

import java.io.ByteArrayInputStream;  import java.io.FileOutputStream;  import java.io.InputStream;  import java.io.OutputStream;  import com.itextpdf.text.Document;  import com.itextpdf.text.pdf.PdfWriter;  import com.itextpdf.tool.xml.XMLWorkerHelper;     /**  * html转pdf  *  * @author zhangwd  * @version 1.0  *  */  public class PdfDemo_4 {         public static void create() throws Exception {             // html中字体非常郁闷          // 1. html中不指定字体,则默认使用英文字体,中文会不显示。          // 2. html中指定的字体必须是英文名称,如宋体:font-family:SimSun;          // 3. html中不能指定自定义字体,必须指定itext支持的字体,还好itext支持字体比较多,常见操作系统带的都支持          // 4. 暂没有找到如何html中支持自定义字体方法,网上都是修改源码实现默认字体中文,也很重要             StringBuilder html = newStringBuilder();          html.append("<html>");          html.append("<bodystyle='font-size:20px;font-family:SimSun;'>");          html.append("<table width='19cm'border='1' cellpadding='0' cellspacing='0'>");          html.append("<tr>");          html.append("<td colspan='2'>凉州词</td>");          html.append("</tr>");          html.append("<tr>");          html.append("<td>黄河远上白云间,一片孤城万仞山。</td>");          html.append("<td>羌笛何须怨杨柳,春风不度玉门关。</td>");          html.append("</tr>");          html.append("</table>");          html.append("</body>");          html.append("</html>");             InputStream is = newByteArrayInputStream(html.toString().getBytes());             OutputStream os = newFileOutputStream("c:/demo.4.pdf");          Document document = new Document();             PdfWriter writer = PdfWriter.getInstance(document,os);             document.open();             // 将html转pdf          XMLWorkerHelper.getInstance().parseXHtml(writer,document, is);             document.close();      }         public static void main(String[]args) throws Exception {          create();      }  }</span>
로그인 후 복사

此处使用了XmlWorker,XmlWorker也是iText官方的,目前和iText版本一起更新,可以讲XHTML转换成pdf,支持大部分样式和标签,是大部分哦,不是全部。

目前我们就用的这个方式,写好html文档,使用时动态替换html中的标记位,然后生成pdf。

使用XHTML转pdf要注意的地方:

1. html中不指定字体,则默认使用英文字体,中文会不显示;网上很多人通过修改源码来实现默认字体中文,也是一种方式,不过感觉比较麻烦。

2. html中指定的字体必须是英文名称;

如宋体:font-family:SimSun;正确

font-family:宋体;则错误,竟然unicode也不行。

3. html中不能指定自定义字体(比如上文中的方正兰亭黑),必须指定iText支持的字体,还好iText支持字体比较多,常见操作系统带的都支持

4. 暂没有找到如何html中支持自定义字体方法。

5. pdf中添加图片也非常简单,例如: 使用iText生成PDF_html/css_WEB-ITnose ,就可以了。

6. XHTML不是HTML,所以任何标签都要完整结束,比如
错误,必须
才行。

5.其他

我们项目的文书目前20多种,以后还会大量增加,不过写一个html模版很简单,需要对html和css熟练,调生成的样式部分比较麻烦(比如文字多了会切掉,不切会影响整体样式,表格线有粗有细,xmlworker不支持全部css等),一般A4纸都是厘米单位的,html中最好也使用厘米,处理简单点。

比如我们的部分模版

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

HTML은 초보자를 위해 쉽게 배우나요? HTML은 초보자를 위해 쉽게 배우나요? Apr 07, 2025 am 12:11 AM

HTML은 간단하고 배우기 쉽고 결과를 빠르게 볼 수 있기 때문에 초보자에게 적합합니다. 1) HTML의 학습 곡선은 매끄럽고 시작하기 쉽습니다. 2) 기본 태그를 마스터하여 웹 페이지를 만들기 시작하십시오. 3) 유연성이 높고 CSS 및 JavaScript와 함께 사용할 수 있습니다. 4) 풍부한 학습 리소스와 현대 도구는 학습 과정을 지원합니다.

HTML, CSS 및 JavaScript의 역할 : 핵심 책임 HTML, CSS 및 JavaScript의 역할 : 핵심 책임 Apr 08, 2025 pm 07:05 PM

HTML은 웹 구조를 정의하고 CSS는 스타일과 레이아웃을 담당하며 JavaScript는 동적 상호 작용을 제공합니다. 세 사람은 웹 개발에서 의무를 수행하고 화려한 웹 사이트를 공동으로 구축합니다.

HTML의 시작 태그의 예는 무엇입니까? HTML의 시작 태그의 예는 무엇입니까? Apr 06, 2025 am 12:04 AM

anexampleStartingtaginhtmlis, whithbeginsaparagraph.startingtagsareessentialinhtmlastheyinitiate rements, definetheirtypes, andarecrucialforstructurituringwebpages 및 smanstlingthedom.

HTML, CSS 및 JavaScript 이해 : 초보자 안내서 HTML, CSS 및 JavaScript 이해 : 초보자 안내서 Apr 12, 2025 am 12:02 AM

WebDevelopmentReliesonHtml, CSS 및 JavaScript : 1) HtmlStructuresContent, 2) CSSSTYLESIT, 및 3) JAVASCRIPTADDSINGINTERACTIVITY, BASISOFMODERNWEBEXPERIENCES를 형성합니다.

Gitee Pages 정적 웹 사이트 배포 실패 : 단일 파일 문제를 해결하고 해결하는 방법 404 오류? Gitee Pages 정적 웹 사이트 배포 실패 : 단일 파일 문제를 해결하고 해결하는 방법 404 오류? Apr 04, 2025 pm 11:54 PM

GiteEpages 정적 웹 사이트 배포 실패 : 404 오류 문제 해결 및 해결시 Gitee ...

웹 주석에서 y 축 위치의 적응 형 레이아웃을 구현하는 방법은 무엇입니까? 웹 주석에서 y 축 위치의 적응 형 레이아웃을 구현하는 방법은 무엇입니까? Apr 04, 2025 pm 11:30 PM

웹 주석 기능에 대한 Y 축 위치 적응 알고리즘이 기사는 Word 문서와 유사한 주석 기능을 구현하는 방법, 특히 주석 간격을 다루는 방법을 모색합니다 ...

HTML, CSS 및 JavaScript : 웹 개발자를위한 필수 도구 HTML, CSS 및 JavaScript : 웹 개발자를위한 필수 도구 Apr 09, 2025 am 12:12 AM

HTML, CSS 및 JavaScript는 웹 개발의 세 가지 기둥입니다. 1. HTML은 웹 페이지 구조를 정의하고 등과 같은 태그를 사용합니다. 2. CSS는 색상, 글꼴 크기 등과 같은 선택기 및 속성을 사용하여 웹 페이지 스타일을 제어합니다.

CSS3 및 JavaScript를 사용하여 클릭 후 주변 사진을 흩어지고 확대하는 효과를 얻는 방법은 무엇입니까? CSS3 및 JavaScript를 사용하여 클릭 후 주변 사진을 흩어지고 확대하는 효과를 얻는 방법은 무엇입니까? Apr 05, 2025 am 06:15 AM

이미지를 클릭 한 후 주변 이미지를 산란 및 확대하는 효과를 얻으려면 많은 웹 디자인이 대화식 효과를 달성해야합니다. 특정 이미지를 클릭하여 주변을 만들 수 있습니다 ...

See all articles