先看效果图
这里说明一下这个页码是独立的覆盖在头部上的,不是写在头部里面 线条是默认的不需要的话设置
cell.setBorder(0);
需要引用的核心包有
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.1</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
代码 调用main方法生成 要指定生成位置 本段代码是指定 D:\document 文件夹下
package com.pdf;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Map;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
@SuppressWarnings(value = {"unused"})
public class BasePDFWrite {
Document document = null;// 建立一个Document对象
PdfWriter writer = null;
public static Font headFont ;
public static Font keyFont ;
public static Font textfont_H ;
public static Font textfont_B ;
// 总页数
PdfTemplate totalPage;
static{
BaseFont bfChinese_H;
try {
/**
* 新建一个字体,iText的方法 STSongStd-Light 是字体,在iTextAsian.jar 中以property为后缀
* UniGB-UCS2-H 是编码,在iTextAsian.jar 中以cmap为后缀 H 代表文字版式是 横版, 相应的 V 代表竖版
*/
bfChinese_H = BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
// bfChinese_H = BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
headFont = new Font(bfChinese_H, 16, Font.BOLD);
keyFont = new Font(bfChinese_H, 16, Font.BOLD);
textfont_H = new Font(bfChinese_H, 8, Font.NORMAL);
textfont_B = new Font(bfChinese_H, 8, Font.NORMAL);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置页面属性
* @param file
*/
public BasePDFWrite(File file) {
// 打印纸张尺寸:长241毫米,宽140毫米,纸张左右各留1厘米空间。
// 200*72/25.4=680
// 140*72/25.4=396
//自定义纸张 前一版本
// Rectangle rectPageSize = new Rectangle(1745,616);
float width = 860;
float height = 445;
//以 Windows 下的 96dpi 来计算,1 pt = px * 96/72 = px * 4/3
float height1 = (float) (height* 96/72) ;
float width1 = (float) (width* 96/72) ;
//测试版
// System.out.println("height1:"+height1+"=============width1:"+width1);
Rectangle rectPageSize = new Rectangle(width1,height1);
// 定义A4页面大小
//Rectangle rectPageSize = new Rectangle(PageSize.A4);
// rectPageSize = rectPageSize.rotate();// 加上这句可以实现页面的横置
document = new Document(rectPageSize,0, 0, 0, 0);
//页边空白
// document.setMargins(-220, -200, 0, 0);
try {
writer = PdfWriter.getInstance(document,new FileOutputStream(file));
writer.setPageEvent(new PageXofY());
document.open();
// String mImgPath = "C://Users//admin//Desktop//55.png";
// Image tImgCover = Image.getInstance(mImgPath);
// /* 设置图片的位置 */
// tImgCover.setAbsolutePosition(0, 0);
// /* 设置图片的大小 */
// tImgCover.scaleAbsolute(1160, 625);
// document.add(tImgCover); //加载图片
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 建表格(以列的数量建)
* @param colNumber
* @return
*/
public PdfPTable createTable(int colNumber){
PdfPTable table = new PdfPTable(colNumber);
try{
table.setHorizontalAlignment(Element.ALIGN_CENTER);
table.getDefaultCell().setBorder(0);
table.setSpacingBefore(10);
table.setWidthPercentage(100);
}catch(Exception e){
e.printStackTrace();
}
return table;
}
/**
* 建表格(以列的宽度比建)
* @param widths
* @return
*/
public static PdfPTable createTable(float[] widths){
PdfPTable table = new PdfPTable(widths);
try{
table.setHorizontalAlignment(Element.ALIGN_CENTER);
table.getDefaultCell().setBorder(0);
table.setSpacingBefore(10);
table.setWidthPercentage(100);
}catch(Exception e){
e.printStackTrace();
}
return table;
}
/**
* 表格中单元格
* @param value
* @param font
* @param align 水平 设置
* @return
*/
public static PdfPCell createCell(String value,Font font,int align){
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setPhrase(new Phrase(value,font));
// 默认 有边框 去0 无边框
// cell.setBorder(0);
return cell;
}
/**
* 表格中单元格
* @param value
* @param font
* @param align_v 垂直 设置
* @param align_h 水平设置
* @param colspan 跨行
* @param rowspan 跨列
* @return
*/
public static PdfPCell createCell(String value,Font font,int align_v,int align_h,int colspan,int rowspan){
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(align_v);
cell.setHorizontalAlignment(align_h);
cell.setColspan(colspan);
cell.setRowspan(rowspan);
cell.setPhrase(new Phrase(value,font));
// 默认 有边框 去0 无边框
// cell.setBorder(0);
return cell;
}
/**
*
* @param image
* @param font
* @param align
* @param colspan
* @param rowspan
* @return
*/
public PdfPCell createCell(Image image, Font font, int align, int colspan,int rowspan) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setColspan(colspan);
cell.setRowspan(rowspan);
cell.setFixedHeight(rowspan*25f);
cell.setImage(image);
return cell;
}
/**
* 建短语
* @param value
* @param font
* @return
*/
public Phrase createPhrase(String value,Font font){
Phrase phrase = new Phrase();
phrase.add(value);
phrase.setFont(font);
return phrase;
}
/**
* 建段落
* @param value
* @param font
* @param align
* @return
*/
public Paragraph createParagraph(String value,Font font,int align){
Paragraph paragraph = new Paragraph();
paragraph.add(new Phrase(value,font));
paragraph.setAlignment(align);
return paragraph;
}
/**
* 设置标题
* @param tbNote
* @param value
* @param indentationLeft
* @param alignment设置文字居中 0靠左 1,居中 2,靠右
* @throws Exception
*/
private void pdfTitle(PdfPTable tbNote, String value, int indentationLeft,int alignment) throws Exception {
PdfPCell cellNo = new PdfPCell();
Paragraph pNo = new Paragraph(value, headFont);
pNo.setAlignment(alignment);
pNo.setIndentationLeft(indentationLeft);
cellNo.addElement(pNo);
cellNo.setBorder(0);
tbNote.addCell(cellNo);
}
private void pdfTitleRight(PdfPTable tbNote, String value, int indentationRight,int alignment) throws Exception {
PdfPCell cellNo = new PdfPCell();
Paragraph pNo = new Paragraph(value, headFont);
pNo.setAlignment(alignment);
pNo.setIndentationRight(indentationRight);
cellNo.addElement(pNo);
cellNo.setBorder(0);
tbNote.addCell(cellNo);
}
/**
* 测试
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
try {
Rectangle rectPageSize = new Rectangle(0,0);
// 1.新建document对象
Document document = new Document(rectPageSize);// 建立一个Document对象
// Document document = new Document(PageSize.A4);// 建立一个Document对象
// 2.建立一个书写器(Writer)与document对象关联
File file = new File("D:\\document\\"+"调拨单.pdf");
file.createNewFile();
new BasePDFWrite(file).printTransferOrder(null);
System.out.println("=========完成==========");
} catch (Exception e) {
e.printStackTrace();
}
}
public void printTransferOrder(Map<String, Object> map ) throws Exception{
// 测试
for (int i = 0; i < 2; i++) {
generatePdfTableTest();
}
document.close();
}
/**
* 单页
* @throws Exception
*/
private void generatePdfTableTest() throws Exception {
String operator = "张三疯";
//页脚
PdfPTable table1 = BasePDFWrite.createTable(new float[] { 10, 25, 10,20 , 17,18});
table1.setTotalWidth(document.right());
table1.addCell(BasePDFWrite.createCell(operator,BasePDFWrite.headFont, Element.ALIGN_RIGHT)); //制单人
table1.addCell(BasePDFWrite.createCell(" ", BasePDFWrite.headFont, Element.ALIGN_CENTER));
table1.addCell(BasePDFWrite.createCell(" ", BasePDFWrite.headFont , Element.ALIGN_CENTER, Element.ALIGN_CENTER, 2, 0));
table1.addCell(BasePDFWrite.createCell(" ", BasePDFWrite.headFont, Element.ALIGN_RIGHT));
table1.addCell(BasePDFWrite.createCell(" ", BasePDFWrite.headFont, Element.ALIGN_LEFT));
table1.writeSelectedRows(0, -1, 0,document.bottom() + 35, writer.getDirectContent());
// 内容
PdfPTable table = createTable(new float[] {12,35,15,10,20,8});
// ==================头 数据 start ==================
String shipper ="中国体彩";
String receiver = "广州东莞经销商";
String sn = "19072503245966299";
String desc = "打印测试";
//换两行
table.addCell(createCell(" ", headFont, Element.ALIGN_LEFT));
table.addCell(createCell(" ", headFont , Element.ALIGN_CENTER, Element.ALIGN_RIGHT, 4, 0));
table.addCell(createCell(" ", headFont, Element.ALIGN_LEFT));
table.addCell(createCell(" ", headFont, Element.ALIGN_LEFT));
table.addCell(createCell(" ", headFont , Element.ALIGN_CENTER, Element.ALIGN_RIGHT, 4, 0));
table.addCell(createCell(" ", headFont, Element.ALIGN_LEFT));
//第一行
table.addCell(createCell(" ", headFont, Element.ALIGN_LEFT));
table.addCell(createCell(" ", headFont , Element.ALIGN_CENTER, Element.ALIGN_RIGHT, 4, 0));
table.addCell(createCell(" ", headFont, Element.ALIGN_LEFT));
//第二行
table.addCell(createCell("2020-11-27", headFont, Element.ALIGN_RIGHT)); //开单日期
table.addCell(createCell(shipper, headFont, Element.ALIGN_RIGHT)); //发货方
table.addCell(createCell(receiver, headFont , Element.ALIGN_CENTER, Element.ALIGN_RIGHT, 2, 0)); //收货方
table.addCell(createCell(sn, headFont, Element.ALIGN_RIGHT)); // 调拨编号
table.addCell(createCell(" ", headFont, Element.ALIGN_LEFT));
//第三行
table.addCell(createCell(desc, headFont , Element.ALIGN_CENTER, Element.ALIGN_LEFT, 4, 0)); //备注
table.addCell(createCell( "2020-11-27", headFont, Element.ALIGN_RIGHT)); //"打印日期"
table.addCell(createCell(" ", headFont, Element.ALIGN_LEFT));
// ==================头 数据 end ========================
// 空两行
table.addCell(createCell(" ", headFont, Element.ALIGN_LEFT));
table.addCell(createCell("", headFont , Element.ALIGN_CENTER, Element.ALIGN_RIGHT, 5, 0));
table.addCell(createCell(" ", headFont, Element.ALIGN_LEFT));
table.addCell(createCell("", headFont , Element.ALIGN_CENTER, Element.ALIGN_RIGHT, 5, 0));
table.addCell(createCell(" ", headFont, Element.ALIGN_LEFT));
table.addCell(createCell("", headFont , Element.ALIGN_CENTER, Element.ALIGN_RIGHT, 5, 0));
table.addCell(createCell(" ", headFont, Element.ALIGN_LEFT));
table.addCell(createCell("", headFont , Element.ALIGN_CENTER, Element.ALIGN_RIGHT, 5, 0));
table.addCell(createCell(" ", headFont, Element.ALIGN_LEFT));
table.addCell(createCell("", headFont , Element.ALIGN_CENTER, Element.ALIGN_RIGHT, 5, 0));
table.addCell(createCell(" ", headFont, Element.ALIGN_LEFT));
table.addCell(createCell("", headFont , Element.ALIGN_CENTER, Element.ALIGN_RIGHT, 5, 0));
//数据行
for (int i = 1; i < 7; i++) {
table.addCell(createCell("2190100552"+i, headFont, Element.ALIGN_LEFT));
table.addCell(createCell("彩票 2019 ", headFont, Element.ALIGN_LEFT));
table.addCell(createCell("张", headFont, Element.ALIGN_LEFT));
table.addCell(createCell("100", headFont, Element.ALIGN_LEFT));
table.addCell(createCell("00001", headFont, Element.ALIGN_RIGHT));
table.addCell(createCell("", headFont, Element.ALIGN_RIGHT));
}
table.setHeaderRows(10);
document.add(table);
document.newPage();
}
}
计算页码工具类
package com.pdf;
import com.itextpdf.text.Document;
import com.itextpdf.text.ExceptionConverter;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
public class PageXofY extends PdfPageEventHelper {
/** The PdfTemplate that contains the total number of pages. */
protected PdfTemplate total;
/** The font that will be used. */
protected BaseFont helv;
/**
* 字体大小
*/
protected int fontSize =16 ;
public void onOpenDocument(PdfWriter writer, Document document) {
total = writer.getDirectContent().createTemplate(100, 100);
try {
helv = BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
} catch (Exception e) {
throw new ExceptionConverter(e);
}
}
/**
* @see com.lowagie.text.pdf.PdfPageEvent#onEndPage(com.lowagie.text.pdf.PdfWriter,
* com.lowagie.text.Document)
*/
public void onEndPage(PdfWriter writer, Document document) {
PdfContentByte cb = writer.getDirectContent();
cb.saveState();
String text = "" + writer.getPageNumber() + " / ";
float textX = document.right()-130;
float textY =document.top()-55;
cb.beginText();
cb.setFontAndSize(helv, fontSize);
//第几页 位置
cb.setTextMatrix(textX, textY );
cb.showText(text);
cb.endText();
// 总页数 位置
cb.addTemplate(total, textX +20, textY);
cb.restoreState();
}
public void onCloseDocument(PdfWriter writer, Document document) {
total.beginText();
total.setFontAndSize(helv, fontSize);
total.setTextMatrix(0, 0);
total.showText(String.valueOf(writer.getPageNumber() - 1));
total.endText();
}
}
下面啰嗦点说说关键代码所在的位置(搜索下面提供的关键代码定位代码位置)
1、复用头部 BasePDFWrite 类
table.setHeaderRows(10);
这是复用前10行的单元格,让其重新出现在下一页的最上面
2、页脚 BasePDFWrite 类
//页脚
PdfPTable table1 = BasePDFWrite.createTable(new float[] { 10, 25, 10,20 , 17,18});
table1.setTotalWidth(document.right());
table1.addCell(BasePDFWrite.createCell(operator,BasePDFWrite.headFont, Element.ALIGN_RIGHT)); //制单人
table1.addCell(BasePDFWrite.createCell(" ", BasePDFWrite.headFont, Element.ALIGN_CENTER));
table1.addCell(BasePDFWrite.createCell(" ", BasePDFWrite.headFont , Element.ALIGN_CENTER, Element.ALIGN_CENTER, 2, 0));
table1.addCell(BasePDFWrite.createCell(" ", BasePDFWrite.headFont, Element.ALIGN_RIGHT));
table1.addCell(BasePDFWrite.createCell(" ", BasePDFWrite.headFont, Element.ALIGN_LEFT));
//设置所在位置
table1.writeSelectedRows(0, -1, 0,document.bottom() + 35, writer.getDirectContent());
每页都新增一个页脚,生成完页面后 在开一个新的页面
document.newPage();
3、动态生成 页码
首先得创建PageXofY 类
在BasePDFWrite 类 初始化 document 时设入值 (最好根据提供的关键代码搜索原文位置去看)
writer.setPageEvent(new PageXofY());
到这里就相当于在页面上打了一个标记
下面是计算页码的代码 上面效果图是 1/2 这样的 实际是拼凑出来的 两个部分 “1/” 第几页 + "2"总页数 位置的话需要大家慢慢调了
public void onEndPage(PdfWriter writer, Document document) {
PdfContentByte cb = writer.getDirectContent();
cb.saveState();
String text = "" + writer.getPageNumber() + " / ";
float textX = document.right()-130;
float textY =document.top()-55;
cb.beginText();
cb.setFontAndSize(helv, fontSize);
//第几页 位置
cb.setTextMatrix(textX, textY );
cb.showText(text);
cb.endText();
// 总页数 位置
cb.addTemplate(total, textX +20, textY);
cb.restoreState();
}