iTextを使用してPDFを生成
13376 ワード
PDF操作クラスライブラリiText
iTextは、PDFファイルをすばやく生成できるJavaクラスライブラリとして有名です.テキスト、テーブル、グラフィックの操作をサポートし、サーブレットと簡単に結合できます.
iTextの更新は大きく変わり、以前のバージョンではPDFスタイルに欠陥がある可能性があり、私が使用した最新の5.5.6パック
1.Maven依存の追加
itextコアパッケージとxmlworderフォントパッケージ
2.直接pdfを生成する
非常に簡単で、文字で段落などを作成し、フォント、間隔、位置合わせなどを設定すればいいので、Hello Worldの例を作ってみましょう.
3.フォント
私达のプロジェクトの文书の字体は比较的に特殊で、例えば宋体(99%はすべてこれでしょう)、中国语は宋(officeをインストールした后に持参します)、宋をまねます_GB 2312など、pdfフォントを研究しましたが、ネット上では中国語フォントを使う方法がたくさんありますが、5.0版以降のiTextにフォントを入れるのは便利です.
xmlworkerのXML WorkerFontProviderは、フォントの入手に便利です.
1.フォルダを登録して、中にどんなフォントがあってもいいです.例えば、私のdemoのフォントです.
2.getFont(フォント名)で入手できますが、フォント名はどこから来たのでしょうか
4.ヘッダー・フッター
iText 5では、以前のバージョンのHeaderFooterオブジェクトでヘッダーとフッターが設定されていません.PdfPageEventを使用してヘッダーのフッターの設定を完了できます.
PdfPageEventは、作成時のpdfのイベントをいくつか提供し、ヘッダー・フッターは各ページにロードされて書き込みが完了します.
ページごとにページ番号を付けるのは簡単ですが、総ページ番号を表示するのは面倒です.iTextはストリームモードの書き込み内容です.最後まで書いてこそ、何ページあるかがわかります.では、総ページ数を表示するのは面倒ですが、面倒は不可能ではありません.
iTextは、リリーステンプレートメソッドを呼び出した後にのみPdfTemplateをOutputStreamに書き込みます.そうしないと、ドキュメントを閉じるまでオブジェクトはメモリに保存されます.
したがって、最後にドキュメントを閉じる前に、PdfTemplateを使用して総ページ番号を書き込むことができます.まずプレースホルダを書いてから、統一的に置き換えることができます.
ハローワールドの例です
5.html回転pdf
結果は悪くなくて、私達の要求を満たすことができますが、しかし比較的に複雑で、動的に1つの表と内容を作成するのは煩雑で、方法はあまりにも乱暴で、ユーザーのドキュメントの内容あるいはフォーマットの変化、プログラムを修正します.
htmlを作成してpdfに変換し、demoは次のようにします.
ここではXmlWorkerを使用していますが、XmlWorkerもiText公式で、現在iTextバージョンとともに更新されています.XHTMLをpdfに変換し、ほとんどのスタイルとラベルをサポートしていますが、ほとんどではありません.すべてではありません.
現在、htmlドキュメントを書き、html内のタグビットを動的に置き換えてpdfを生成する方法を使用しています.
XHTMLを使用してpdfを転送する際の注意点:
1. htmlにフォントを指定しないと、デフォルトでは英語のフォントが使用され、中国語は表示されません.
2. htmlで指定したフォントは英語名でなければなりません.宋体:font-family:SimSun;正しいfont-family:宋体;するとエラーで、unicodeもだめだった.
3. htmlではカスタムフォント(例えば、上の方正蘭亭黒)を指定することはできませんが、itextの一般的なオペレーティングシステムのフォントはサポートされています.ubuntuにマイクロソフトの黒がなければ、windowsから黒のフォントYaheiをコピーすることができます.ttfはubuntuに/usr/share/fonts/パスを入れます.
4. pdfに画像を追加するのも簡単です.例えば、,でいいです.
5. XHTMLはHTMLではないので、
エラーなどのラベルはすべて完全に終了しなければなりません.
htmlのテンプレートを書くのは簡単で、htmlとcssに熟練する必要があります.生成されたスタイルの部分を調整するのは面倒です(例えば、文字が多くなると切ります.切らないと全体のスタイルに影響します.表の線が太くて細いので、xmlworkerはすべてのcssをサポートしません).一般的にA 4紙はセンチメートル単位で、htmlの中でもセンチメートルを使ったほうがいいです.処理は簡単です.
iTextは、PDFファイルをすばやく生成できるJavaクラスライブラリとして有名です.テキスト、テーブル、グラフィックの操作をサポートし、サーブレットと簡単に結合できます.
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 iText;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPHeaderCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import org.junit.Test;
import java.io.FileOutputStream;
/**
* author wangnian
* date 2016/4/1
*/
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);
// pdf
FileOutputStream fileOutputStream= new FileOutputStream("D:/demo.pdf");
// writer, writer
PdfWriter writer = PdfWriter.getInstance(document,fileOutputStream);
// 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("wangnian");
//
document.addSubject(" ");
//
document.addTitle(" ");
//
document.add(new Paragraph(title, font));
document.add(new Paragraph(content, font));
document.add(new Paragraph("
\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();
}
@Test
public void test() {
try {
create();
System.out.println(" ");
}catch (Exception ex){
System.out.println(" ");
}
}
}
3.フォント
私达のプロジェクトの文书の字体は比较的に特殊で、例えば宋体(99%はすべてこれでしょう)、中国语は宋(officeをインストールした后に持参します)、宋をまねます_GB 2312など、pdfフォントを研究しましたが、ネット上では中国語フォントを使う方法がたくさんありますが、5.0版以降のiTextにフォントを入れるのは便利です.
package iText;
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;
import org.junit.Test;
/**
*
*
* author wangnian
* date 2016/4/1
*
*/
public class PdfDemo_2 {
public static void create() throws Exception {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document,new FileOutputStream("D:/demo2.pdf"));
String title = " ";
String content = " , 。 , 。";
document.open();
document.add(new Paragraph(title, getFont(" ")));
document.add(new Paragraph(content, getFont(" ")));
document.close();
writer.close();
}
private static Font getFont(String fontName) {
// xmlworker html pdf , , itext
// xmlworker , ,
FontFactoryImp fp = new XMLWorkerFontProvider();
// , , src/font
fp.registerDirectory(PdfDemo_2.class.getClassLoader().getResource("weiruanyahei").getFile(), true);
//
return fp.getFont(fontName);
// , XMLWorkerFontProvider, ,
}
@Test
public void test() throws Exception {
create();
System.out.println(" ");
}
}
xmlworkerのXML WorkerFontProviderは、フォントの入手に便利です.
1.フォルダを登録して、中にどんなフォントがあってもいいです.例えば、私のdemoのフォントです.
2.getFont(フォント名)で入手できますが、フォント名はどこから来たのでしょうか
4.ヘッダー・フッター
iText 5では、以前のバージョンのHeaderFooterオブジェクトでヘッダーとフッターが設定されていません.PdfPageEventを使用してヘッダーのフッターの設定を完了できます.
PdfPageEventは、作成時のpdfのイベントをいくつか提供し、ヘッダー・フッターは各ページにロードされて書き込みが完了します.
ページごとにページ番号を付けるのは簡単ですが、総ページ番号を表示するのは面倒です.iTextはストリームモードの書き込み内容です.最後まで書いてこそ、何ページあるかがわかります.では、総ページ数を表示するのは面倒ですが、面倒は不可能ではありません.
iTextは、リリーステンプレートメソッドを呼び出した後にのみPdfTemplateをOutputStreamに書き込みます.そうしないと、ドキュメントを閉じるまでオブジェクトはメモリに保存されます.
したがって、最後にドキュメントを閉じる前に、PdfTemplateを使用して総ページ番号を書き込むことができます.まずプレースホルダを書いてから、統一的に置き換えることができます.
ハローワールドの例です
package iText;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
/**
* iText5 HeaderFooter <br>
* , PdfPageEventHelper 。<br>
* , 、 、 。<br>
*
* author wangnian
* date 2016/4/1
*
*/
public 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, Document document) {
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);
}
}
package iText;
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;
import org.junit.Test;
/**
* 、
* author wangnian
* date 2016/4/1
*/
public class PdfDemo_3 {
public static void create() throws Exception {
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
PdfWriter writer = PdfWriter.getInstance(document,new FileOutputStream("d:/demo3.pdf"));
//
writer.setPageEvent(new MyHeaderFooter());
String title = " ";
String content = " , 。 , 。";
document.open();
Font font = new XMLWorkerFontProvider().getFont(" ");
for (int i = 0; i <100; i++) {
document.add(new Paragraph(title, font));
document.add(new Paragraph(content,font));
document.add(new Paragraph("
"));
}
document.close();
writer.close();
}
@Test
public void test() throws Exception {
create();
System.out.println(" ");
}
}
5.html回転pdf
結果は悪くなくて、私達の要求を満たすことができますが、しかし比較的に複雑で、動的に1つの表と内容を作成するのは煩雑で、方法はあまりにも乱暴で、ユーザーのドキュメントの内容あるいはフォーマットの変化、プログラムを修正します.
htmlを作成してpdfに変換し、demoは次のようにします.
package iText;
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;
import org.junit.Test;
/**
* html pdf
* author wangnian
* date 2016/4/1
*
*/
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 = new StringBuilder();
html.append("<html>");
html.append("<body style='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 = new ByteArrayInputStream(html.toString().getBytes());
OutputStream os = new FileOutputStream("D:/demo4.pdf");
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document,os);
document.open();
// html pdf
XMLWorkerHelper.getInstance().parseXHtml(writer,document, is);
document.close();
}
@Test
public void test() throws Exception {
create();
System.out.println(" ");
}
}
ここではXmlWorkerを使用していますが、XmlWorkerもiText公式で、現在iTextバージョンとともに更新されています.XHTMLをpdfに変換し、ほとんどのスタイルとラベルをサポートしていますが、ほとんどではありません.すべてではありません.
現在、htmlドキュメントを書き、html内のタグビットを動的に置き換えてpdfを生成する方法を使用しています.
XHTMLを使用してpdfを転送する際の注意点:
1. htmlにフォントを指定しないと、デフォルトでは英語のフォントが使用され、中国語は表示されません.
2. htmlで指定したフォントは英語名でなければなりません.宋体:font-family:SimSun;正しいfont-family:宋体;するとエラーで、unicodeもだめだった.
3. htmlではカスタムフォント(例えば、上の方正蘭亭黒)を指定することはできませんが、itextの一般的なオペレーティングシステムのフォントはサポートされています.ubuntuにマイクロソフトの黒がなければ、windowsから黒のフォントYaheiをコピーすることができます.ttfはubuntuに/usr/share/fonts/パスを入れます.
4. pdfに画像を追加するのも簡単です.例えば、,でいいです.
5. XHTMLはHTMLではないので、
エラーなどのラベルはすべて完全に終了しなければなりません.
htmlのテンプレートを書くのは簡単で、htmlとcssに熟練する必要があります.生成されたスタイルの部分を調整するのは面倒です(例えば、文字が多くなると切ります.切らないと全体のスタイルに影響します.表の線が太くて細いので、xmlworkerはすべてのcssをサポートしません).一般的にA 4紙はセンチメートル単位で、htmlの中でもセンチメートルを使ったほうがいいです.処理は簡単です.