iTEXT 使用
读取模板, 写入响应流, 自定义绘制
public class PdfUtilBean {
private PdfStamper stamper;
private PdfReader reader;
}
// 获取pdf模板
public static PdfUtilBean getPdfStamper(HttpServletResponse response,String readPdfName){
PdfUtilBean bean = new PdfUtilBean();
PdfStamper stamper = null;
try {
OutputStream bos = response.getOutputStream();
ClassPathResource classPathResource = new ClassPathResource(StrUtil.concat(true, "/pdffile/", readPdfName));
InputStream stream = classPathResource.getStream();
PdfReader reader = new PdfReader(stream);
stamper = new PdfStamper(reader, bos);
return bean;
} catch (Exception e) {
log.error("获取PDF操作对象异常,",e);
}
return null;
}
//写入response
public static void outPrint(HttpServletResponse response,PdfStamper stamper,String outFileName) {
try {
OutputStream bos = response.getOutputStream();
//设置为生成的pdf不可修改文本域
stamper.setFormFlattening(true);
stamper.close();
//直接写入返回的流
response.setContentType("application/x-download");
response.addHeader("Content-Disposition", "attachment;filename=" + outFileName + ".pdf");
bos.flush();
} catch (Exception e) {
log.error("输出PDF对象到输出流异常,",e);
}
}
//自定义绘制
PdfContentByte cb = stamper.getOverContent(1);// 1为页数, pdf的页数
ColumnText ct = new ColumnText(cb);
//设置对齐方式
ct.setAlignment(Element.ALIGN_CENTER);
//设置此正方体 布局
ct.setSimpleColumn(36, 36, PageSize.A4.getWidth()-36, PageSize.A4.getHeight()-590);
//ct.addElement(table); //添加元素
int status = ct.go();// 绘制
while (ColumnText.hasMoreText(status)){// 绘制不完, 新增页绘制, 直到绘制完
stamper.insertPage(pdfStamper.getReader().getNumberOfPages() + 1, pdfStamper.getReader().getPageSizeWithRotation(1));
PdfContentByte canvas = stamper.getOverContent(pdfStamper.getReader().getNumberOfPages());
ct.setCanvas(canvas);
ct.setSimpleColumn(36, 36, PageSize.A4.getWidth()-36, PageSize.A4.getHeight()-70);
status = ct.go();
}
添加图片, 通过设置按钮的图标方法实现添加图片
PushbuttonField ad = form.getNewPushbuttonFromField(imageFieldName);
ad.setLayout(PushbuttonField.LAYOUT_ICON_ONLY);
ad.setProportionalIcon(true);
ad.setImage(Image.getInstance("E:/signature/signature.png"));
form.replacePushbuttonField("advertisement", ad.getField());
为模板添加动态表格
PdfPTable table = new PdfPTable(25);
BaseFont baseFont2 = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
Font font2 = new Font(baseFont2);
font2.setSize(14);
PdfPCell questionTypeCell = new PdfPCell(new Paragraph("问: ", font2));
// 定义一个表格单元的跨度
questionTypeCell.setColspan(2);
questionTypeCell.disableBorderSide(15);
// 把单元加到表格中
table.addCell(questionTypeCell);
PdfPCell questionContentCell = new PdfPCell(new Paragraph("你好啊?", font2));
// 定义一个表格单元的跨度
questionContentCell.setColspan(23);
//设置边框 样式, 13 为只保留下, 15全都隐藏
questionContentCell.disableBorderSide(15);
// 把单元加到表格中
table.addCell(questionContentCell);
//写入
PdfContentByte cb = stamper.getOverContent(1);
ColumnText ct = new ColumnText(cb);
ct.setAlignment(Element.ALIGN_CENTER);
//前两个参数应该是 左右页边距, 后两个参数是相对于PDF 左上角为坐标原点的绝对定位
ct.setSimpleColumn(36, 36, PageSize.A4.getWidth()-36, PageSize.A4.getHeight()-590);
//添加元素
ct.addElement(table);
int status = ct.go();
// 动态添加新页
while (ColumnText.hasMoreText(status)){
stamper.insertPage(pdfStamper.getReader().getNumberOfPages() + 1, pdfStamper.getReader().getPageSizeWithRotation(1));
PdfContentByte canvas = stamper.getOverContent(pdfStamper.getReader().getNumberOfPages());
ct.setCanvas(canvas);
ct.setSimpleColumn(36, 36, PageSize.A4.getWidth()-0, PageSize.A4.getHeight()-70);
status = ct.go();
}
边框样式
//隐藏上边框
// cell.disableBorderSide(1);
//隐藏下边框
// cell.disableBorderSide(2);
//隐藏上、下边框
//cell.disableBorderSide(3);
//隐藏左边框
//cell.disableBorderSide(4);
//隐藏左、上边框
//cell.disableBorderSide(5);
//隐藏左、下边框
//cell.disableBorderSide(6);
//隐藏左、上、下边框
//cell.disableBorderSide(7);
//隐藏右边框
//cell.disableBorderSide(8);
//隐藏右、上边框
// cell.disableBorderSide(9);
//隐藏右、下边框
//cell.disableBorderSide(10);
//隐藏右、上、下边框
//cell.disableBorderSide(11);
//隐藏左、右边框
//cell.disableBorderSide(12);
//隐藏上、左、右边框
//cell.disableBorderSide(13);
//隐藏下、左、右边框
//cell.disableBorderSide(14);
//隐藏全部
//cell.disableBorderSide(15);
使用table手动处理换行
核心代码:
float widthPoint = font.getCalculatedBaseFont(true).getWidthPoint(sb.toString(), font.getCalculatedSize());
/**
* 把给定的字符串 通过给定的widthPoint值 在table中生成每行内容
*
* @param table
* @param questionContent
* @param maxWidthPoint
* @param font
* @throws DocumentException
* @throws IOException
*/
public static void addRow(PdfPTable table, String questionContent, float maxWidthPoint, Font font) throws DocumentException, IOException {
StringBuilder contentTemp = new StringBuilder(questionContent);
for (Chunk chunk = getOneLine(contentTemp, font, maxWidthPoint); null != chunk; chunk = getOneLine(contentTemp, font, maxWidthPoint)){
Paragraph paragraph2 = new Paragraph(chunk);
paragraph2.setIndentationLeft(50);
//第2列
PdfPCell questionContentCell = new PdfPCell(paragraph2);
// 定义一个表格单元的跨度
questionContentCell.setColspan(24);
questionContentCell.setHorizontalAlignment(Element.ALIGN_JUSTIFIED);
questionContentCell.disableBorderSide(13);
// 把单元加到表格中
table.addCell(questionContentCell);
}
}
/**
* 根据maxWidthPoint从字符串种获取table的一行内容
*
* @param contentTemp
* @param font
* @param maxWidthPoint 允许的最大宽度
* @return Chunk
*/
//不能在首行出现的标点符号集合
private static final List<String> CHARACTER = Arrays.asList("。",",","!",";","(",")","、"); // 不全可以手动添加
public static Chunk getOneLine(StringBuilder contentTemp, Font font, float maxWidthPoint){
//允许的最大宽度
StringBuilder sb = new StringBuilder();
for (;contentTemp.length()>0;){
CharSequence string = contentTemp.subSequence(0, 1);
sb.append(string);
float widthPoint = font.getCalculatedBaseFont(true).getWidthPoint(sb.toString(), font.getCalculatedSize());
// 换行符判断
boolean isNewLine = false;
if (contentTemp.length()>1){ // 这里判断换行符 一个换行符就在table中新起一行
String newline = contentTemp.subSequence(0, 2).toString();
//建议: 这里只判断windows换行符, 所以在调用当前方法时请确保String的replaceAll方法统一为windows换行符
if (newline.matches("\r\n")){
widthPoint = maxWidthPoint+1; // 使widthPoint大于maxWidthPoint, 后面的内容新起一行
contentTemp.delete(0,2);
isNewLine= true;
}
}
/**
* 因为每行开始处不能有标点符号,当widthPoint大于maxWidthPoint或者widthPoint等于maxWidthPoint要分两种情况:
*
* 第一种: widthPoint大于maxWidthPoint
* 判断currentStr即需要删除的那个字符是否是标点符号, 如果是, 就把当前字符的前一个字符也截取到下一行去(即sb要去掉2个字符);
* 第二种: widthPoint等于maxWidthPoint
* 判断nextOneChar即下一个字符是否是标点符号, 如果是, 就把当前行的最后一个字符放入下一行开始处
* 注意: 此处理方法无法处理标点符号连续的情况, 如: 你好啊,,,是谁啊!!
*/
if (widthPoint >= maxWidthPoint){
if (widthPoint > maxWidthPoint){
String currentStr = sb.subSequence(sb.length()-1, sb.length()).toString();
//超过maxWidth 删除倒数第一个字符
sb.deleteCharAt(sb.length()-1);
//如果当前字符是标点符号
//如果是因为换行符导致的widthPoint > maxWidth, 不做判断
if (CHARACTER.contains(currentStr) && !isNewLine){
//把当数第二个字符插入到下一行开始
String lastButOne = sb.substring(sb.length() - 1, sb.length());
contentTemp.insert(0, lastButOne);
sb.deleteCharAt(sb.length()-1);
}
}else{
if(contentTemp.length() >= 2){
String nextOneChar = contentTemp.subSequence(1, 2).toString();
if (CHARACTER.contains(nextOneChar)) {
sb.deleteCharAt(sb.length()-1);
}
}
}
break;
}
// 如果没有超过最大widthPoint, 减去字符串一个字符
if (widthPoint != maxWidthPoint) {
contentTemp.deleteCharAt(0);
}
}
if (sb.length() == 0){
return null;
}
Chunk chunk = new Chunk(sb.toString());
chunk.setFont(font);
chunk.setLineHeight(20f);
return chunk;
}
效果如下:


浙公网安备 33010602011771号