当前位置: 移动技术网 > IT编程>开发语言>Java > Java使用itext5实现PDF表格文档导出

Java使用itext5实现PDF表格文档导出

2020年03月09日  | 移动技术网IT编程  | 我要评论

最近拿到一个需求,需要导出pdf文档,市面上可以实现的方法有很多,经过测试和调研决定使用itext5来实现,话不多说,说干就干。

1.依赖导入

<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
  <dependency>
   <groupid>com.itextpdf</groupid>
   <artifactid>itextpdf</artifactid>
   <version>5.5.13.1</version>
  </dependency>
  <!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
  <dependency>
   <groupid>com.itextpdf</groupid>
   <artifactid>itext-asian</artifactid>
   <version>5.2.0</version>
  </dependency>

这里说明下:上面的依赖就是主要实现pdf生成的,下面的依赖是中文字体相关依赖;

2.pdf表格导出实现

1.导出pdf

//   1.打开文档并设置基本属性
   document document = new document();
//   2.设置请求头,encode文件名
   response.setcontenttype("application/pdf;charset=utf-8");
   response.setheader("content-disposition", 
   "attachment; filename=" + java.net.urlencoder.encode("" + 
   recorddto.gettitle() + ".pdf", "utf-8"));
//   3.通过流将pdf实例写出到浏览器
   pdfwriter writer = pdfwriter.getinstance(document, response.getoutputstream());
 

至此导出pdf已经实现了,只是这个pdf中什么内容都没有,明白这一点,接下来做的就是给这个文档“加料”咯(这里的response就是httpservletresponse)。

2.页面美化

//    这里的wirter就是上文的writer
   writer.setviewerpreferences(pdfwriter.pagemodeusethumbs);
   writer.setpagesize(pagesize.a4);
 

这里设置了文档的显示缩略图以及文档大小为a4;

3.中文字体设置

public static font getpdfchinesefont() throws exception {
  basefont bfchinese = basefont.createfont("stsongstd-light", "unigb-ucs2-h",
    basefont.not_embedded);
  font fontchinese = new font(bfchinese, 12, font.normal);
  fontchinese.setcolor(basecolor.black);
  fontchinese.setsize(11);
  return fontchinese;
 }
 

这个方法设置了中文字体样式,感兴趣的同学可以试试其他的样式,例如:字体颜色,大小,字体都可以修改;

4.输出表格内容到文档

// 首先打开文档
document.open();
// 向文档中添加表格数据
private static void printbasicinfo(shopapplyrecorddto recorddto, document document, font font) throws documentexception {
// 表格中的数据
  object[][] basicdatas = {
    {"标题","xxx申请", "审批编号","1234"},
    {"申请人","小明", "申请商铺","xxx商场"},
    {"申请日期","2020/1/16", "审批结果","同意")}};
// 每个cell的宽度
  float[] widthss = {50, 200, 50, 200};
//   创建一个表格,每一行有四个cell
  pdfptable basictable = new pdfptable(widthss);
// 外层循环表格的行
  for (int i = 0; i < basicdatas.length; i++) {
// 内层循环每一行具体数据
   for (int j = 0; j < basicdatas[i].length; j++) {
//   新建一个cell
    pdfpcell cell = new pdfpcell();
// 这个方法是统一设置表格和cell的样式,下面会写 
    settablestyle(basictable, cell);
// cell中需要填充数据的格式
    paragraph paragraph = 
    new paragraph(strutil.tostring(basicdatas[i][j]), font);
// 设置cell的值
    cell.setphrase(paragraph);
// 将cell添加到表格中
    basictable.addcell(cell);
   }
  }
// 将表格添加到文档中
  document.add(basictable);
 }
// 结束时要关闭文档
document.close();
 

大功告成,现在导出的pdf中已经有了类似这样的表格了:

当然你的样式会很丑,接下来我们来设置下样式。

5.表格和cell样式设置

public static void settablestyle(pdfptable table, pdfpcell cell) {
// 设置表格样式
  table.setlockedwidth(true);
  table.settotalwidth(500);
  table.sethorizontalalignment(element.align_left);
// 设置单元格样式
  cell.setminimumheight(35);
  cell.sethorizontalalignment(element.align_center);
  cell.setverticalalignment(element.align_middle);
  cell.setbackgroundcolor(basecolor.white);
  cell.setborder(0);
  cell.setborderwidthtop(0.1f);
  cell.setborderwidthbottom(0.1f);
  cell.setborderwidthleft(0.1f);
  cell.setborderwidthright(0.1f);
  cell.setbordercolorbottom(basecolor.black);
  cell.setbordercolorleft(basecolor.black);
  cell.setbordercolorright(basecolor.black);
  cell.setbordercolortop(basecolor.black);
  cell.setpadding(3);
 }
 

api方法还是比较易懂的,这里就不多赘述了,不明白的自己设置试试就可以做出自己喜欢的样式咯。

6.页眉和页码的设置

这里说明下,itext2和itext5的api有很大不同,2的版本有一个专门的headerfooter类来设置样式,5的版本没有这样的类,取而代之的是pdfpageeventhelper这样一个事件处理类,这里大家千万别弄混了,这两个版本的api互相不兼容;
这里首先写一个pdfpageeventhelper的子类来实现页眉页码的打印:

public class headerfooter extends pdfpageeventhelper {
// 这里是业务相关的属性可以无视
 private shopapplyrecorddto recorddto;
 private sysuserinfo userinfo;
// 大部分情况下页眉的值是动态的,这里可以在初始化的时候进行参数传递
 public headerfooter(shopapplyrecorddto recorddto, sysuserinfo userinfo) {
  this.recorddto = recorddto;
  this.userinfo = userinfo;
 }

 public headerfooter() {
 }

 public shopapplyrecorddto getrecorddto() {
  return recorddto;
 }

 public void setrecorddto(shopapplyrecorddto recorddto) {
  this.recorddto = recorddto;
 }

 public sysuserinfo getuserinfo() {
  return userinfo;
 }

 public void setuserinfo(sysuserinfo userinfo) {
  this.userinfo = userinfo;
 }
// 这个方法就是实现页眉和页码的关键:它的含义是每当页面结束会执行该方法
 @override
 public void onendpage(pdfwriter writer, document document) {
  font font = null;
  try {
   font = getpdfchinesefont();
  } catch (exception e) {
   e.printstacktrace();
  }
  simpledateformat format = new simpledateformat("yyyy/mm/dd hh:mm");
// 设置页眉:这里图省事就用空格来实现左中右三个位置的页眉,其实可以写三个,通过element.align_left来控制页眉的位置,document.left()/document.top()这两个可以设置页眉具体位置类似于html的上下调整,大家可以多试试
  columntext.showtextaligned(writer.getdirectcontent(), 
  element.align_left,
  new phrase("所属项目:" + recorddto.getmallname() + "             打印时间:" + format.format(new date()) + "         打印人:" + userinfo.getusername(), font),
  document.left(),
  document.top() + 3, 0);
// 获得一个名为“art”的盒子 
  rectangle rect = writer.getboxsize("art");
// 设置页码:这里的页码位置已经设置好,大家可直接使用,至于1/20这种效果的页码实现则十分复杂,如有需求请自行百度/谷歌
  columntext.showtextaligned(writer.getdirectcontent(),
  element.align_center, 
  new phrase(string.format("%d", writer.getpagenumber())),
  (rect.getleft() + rect.getright()) / 2, 
  rect.getbottom() - 18, 0);
 }

 public static font getpdfchinesefont() throws exception {
  basefont bfchinese = basefont.createfont("stsongstd-light", "unigb-ucs2-h",
    basefont.not_embedded);
  font fontchinese = new font(bfchinese, 12, font.normal);
  fontchinese.setcolor(basecolor.black);
  fontchinese.setsize(11);
  return fontchinese;
 }
}
 
接下来就很简单了,将我们的headerfooter设置给pdfwriter对象即可:

// 新建headerfooter并传递需要的参数
headerfooter headerfooter = new headerfooter(recorddto, userinfo);
// 新建一个盒子
rectangle rect = new rectangle(36, 54, 559, 788);
// 设置名称为“art”,上面get的就是这个盒子了
writer.setboxsize("art", rect);
writer.setpageevent(headerfooter);
// 这个可以设置内容的margin
document.setmargins(45f, 45f, 65f, 50f);
 

7.效果展示

8.总结

好了,到这里打印pdf文档就完全实现了,其实itext5还有很多功能,比如:文本,图片,链接都可以实现,大家如果有需求可以去官方文档看看,也可以留言问我,小弟第一篇博客,有什么错误希望大家在留言中提出,我好及时改正,免得误人子弟哈哈。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网