java 后端生成pdf模板合并单元格表格的案例
程序员文章站
2023-02-18 11:50:39
这里只放部分片段的代码java中使用二维数组生成表格非常方便,但是每一维的数组都需要排好序,而且,在java中所谓的二维数组,三维数组等,其实都是多个一维数组组成的/** * 添加子女教育规划表。...
这里只放部分片段的代码
java中使用二维数组生成表格非常方便,但是每一维的数组都需要排好序,而且,在java中所谓的二维数组,三维数组等,其实都是多个一维数组组成的
/** * 添加子女教育规划表。 * @param name 子女姓名 * @param educationitems 某个孩子的教育规划的二维数组,每列依次是:学程阶段、年数、费用支出(元)/年、年增长率 * @param spacing * @throws documentexception * @throws ioexception */ private void addeducationtable(string name, string[][] educationitems, float spacing) throws documentexception, ioexception { addparagraphtext(name + "的教育支出规划如下:", getmaintextfont(), 0, spacing_5, leading_mult);//标题字段 //以下是表头 float[] colwidth = new float[] { mm2px_width(34f), mm2px_width(34f), mm2px_width(34f), mm2px_width(34f), mm2px_width(34f) }; string[] colname = { "学程阶段", "年数", "规划值(首次)","发生值(首次)", "年增长率" };//表头列的一维数组 int[] colalignment = {element.align_left, element.align_right, element.align_right, element.align_right, element.align_right }; //表头有几列就写几个对齐方式 float[] colpaddingleft = { 3f, 3f, 3f, 3f, 3f }; float[] colpaddingright = { 3f, 3f, 3f, 3f, 3f }; font[] colfont = { gettabcelltextfont(), gettabcelltextfont(), gettabcelltextfont(), gettabcelltextfont(), gettabcelltextfont() };//字体及颜色的设置 educationitems=swap(educationitems, 3, 4);//这是排序二维数组,把第4列换到第3行(从0开始计数) pdfptable table = tabletemplate(educationitems, colwidth, colname, colalignment, colpaddingleft, colpaddingright, colfont);//生成表格 table.setspacingafter(mm2px_height(spacing)); this._document.add(table);//生成到pdf去,代码就不贴了 } /** * @param items 二维数组表示的表 * @param colwidth 各列的宽度(像素) * @param colname 各列的名称 * @param colalignment 各列的水平对齐方式 * @param colpaddingleft 各列的左padding * @param colpaddingright 各列的右padding * @param colfont 各列的字体 * @return * @throws documentexception * @throws ioexception */ private pdfptable tabletemplates(string[][] items, float[] colwidth, string[] colname, int[] colalignment, float[] colpaddingleft, float[] colpaddingright, font[] colfont) throws documentexception, ioexception { pdfptable inttable = new pdfptable(colwidth.length); inttable.settotalwidth(colwidth); inttable.setlockedwidth(true); inttable.getdefaultcell().setleading(mm2px_height(leading_cell_text), 1f); //单元格内文字行间距 inttable.getdefaultcell().setbordercolor(color_cell_border); //边框颜色 inttable.setheaderrows(1); //第一行做表头,跨页再现表头 //单元格可以跨页 inttable.setsplitlate(false); inttable.setsplitrows(true); /*********************************************************************************************/ /***********************************以下是表头标题栏*******************************************/ float headerheight = mm2px_height(table_header_height); inttable.getdefaultcell().setfixedheight(headerheight); //行高 inttable.getdefaultcell().setborder(rectangle.no_border); //无边框 for(int i = 0; i < colname.length; i++) { inttable.getdefaultcell().setbackgroundcolor(color_tab_header); //表头背景 inttable.getdefaultcell().sethorizontalalignment(colalignment[i]); inttable.getdefaultcell().setpaddingleft(colpaddingleft[i]); inttable.getdefaultcell().setpaddingright(colpaddingright[i]); inttable.addcell(new paragraph(colname[i], gettabheadertextfont())); } /*********************************************************************************************/ /***********************************以下是表格每行*********************************************/ float rowheight = mm2px_height(table_row_height); inttable.getdefaultcell().setminimumheight(rowheight); //单元格内文字不确定,不能设置成固定行高 inttable.getdefaultcell().setbackgroundcolor(color_cell_back_white); for(int i = 0; i < items.length; i++) { if(i == items.length - 1) //最后一行有合并单元格 { inttable.getdefaultcell().setcolspan(6);//设置具体合并哪一列 inttable.getdefaultcell().sethorizontalalignment(colalignment[0]); inttable.getdefaultcell().setpaddingleft(colpaddingleft[0]); inttable.getdefaultcell().setpaddingright(colpaddingright[0]); inttable.getdefaultcell().setborder(rectangle.left | rectangle.right | rectangle.bottom); inttable.addcell(new paragraph(items[i][0], colfont[0])); }else{ for(int j = 0; j < items[i].length; j++) { if(j == 0)inttable.getdefaultcell().setborder(rectangle.left | rectangle.right | rectangle.bottom); else inttable.getdefaultcell().setborder(rectangle.right | rectangle.bottom); if(j < colalignment.length){ inttable.getdefaultcell().sethorizontalalignment(colalignment[j]); inttable.getdefaultcell().setpaddingleft(colpaddingleft[j]); inttable.getdefaultcell().setpaddingright(colpaddingright[j]); inttable.addcell(new paragraph(items[i][j], colfont[j])); } } } } /*********************************************************************************************/ return inttable; } /* *二维数组根据指定列排序到指定位置的方法,f2要大于f1 */ public string[][] swap(string[][] data,int f1,int f2){ for (int i = 0; i < data.length; i++) { string tamp=data[i][f2]; for (int j = f2; j >f1; j--) { data[i][j]=data[i][j-1]; } data[i][f1]=tamp; } return data; } /** * @return 获取表头标题栏字体。 * @throws documentexception * @throws ioexception */ private static font gettabheadertextfont() throws documentexception, ioexception { return getfont(gdm.geturlstring(gdm.font_simhei), font_size_tab_header_text, font.normal, color_tab_header_text); } /** * @return 获取单元格文字字体。 * @throws documentexception * @throws ioexception */ private static font gettabcelltextfont() throws documentexception, ioexception { return getfont(gdm.geturlstring(gdm.font_simhei), font_size_tab_cell_text, font.normal, gdm.color_666666); } /** * @return 获取标题字体。 * @throws documentexception * @throws ioexception */ private static font gettitlefont() throws documentexception, ioexception { return getfont(gdm.geturlstring(gdm.font_header_ch), font_size_title, font.normal, gdm.color_333333); } /** * @return 获取标题字体(小)。 * @throws documentexception * @throws ioexception */ private static font gettitlefont_small() throws documentexception, ioexception { return getfont(gdm.geturlstring(gdm.font_header_ch), font_size_title - 1f, font.normal, gdm.color_333333); } /** * @return 获取正文字体。 * @throws documentexception * @throws ioexception */ private static font getmaintextfont() throws documentexception, ioexception { return getfont(gdm.geturlstring(gdm.font_normal), font_size_maintext, font.normal, gdm.color_666666); }
加一个生成pdf常用的格式工具类
import java.io.ioexception; import java.net.malformedurlexception; import com.itextpdf.text.badelementexception; import com.itextpdf.text.basecolor; import com.itextpdf.text.chunk; import com.itextpdf.text.document; import com.itextpdf.text.documentexception; import com.itextpdf.text.element; import com.itextpdf.text.font; import com.itextpdf.text.image; import com.itextpdf.text.pagesize; 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.columntext; import com.itextpdf.text.pdf.pdfcontentbyte; import com.itextpdf.text.pdf.pdfpcell; import com.itextpdf.text.pdf.pdfptable; import com.itextpdf.text.pdf.pdfwriter; public class finplan { protected document _document; //文档对象 protected pdfwriter _writer; //pdf文档输出器 public finplan(document document, pdfwriter writer) { super(); this._document = document; this._writer = writer; } /** * 像素到毫米的转换(高度) * @param px 纵向像素 * @return */ public static float px2mm_height(float px) { return px * gdm.page_height / pagesize.a4.getheight(); } /** * 在指定位置写入文字 * @param text 需要写入的文字 * @param xpoint 距左边位置(毫米) * @param ypoint 距底边位置(毫米) */ protected void writeonsplocation(float xpoint, float ypoint, string text, font font) { pdfcontentbyte pcb = this._writer.getdirectcontent(); xpoint = mm2px_width(xpoint); ypoint = mm2px_height(ypoint); paragraph prg = new paragraph(text, font); columntext.showtextaligned(pcb, pdfcontentbyte.align_left, prg, xpoint, ypoint, 0); } /** * 添加标题。 * @param title 标题 * @param font 标题字体 * @param spacingbefore 标题前的空白(毫米) * @throws documentexception * @throws ioexception */ protected void addtitle(string title, font font, float spacingbefore) throws documentexception, ioexception { addtitle(title, font, spacingbefore, 0f); } /** * 添加标题。 * @param title 标题 * @param font 标题字体 * @param spacingbefore 标题前的空白(毫米) * @param spacingafter 标题后的空白(毫米) * @throws documentexception * @throws ioexception */ protected void addtitle(string title, font font, float spacingbefore, float spacingafter) throws documentexception, ioexception { paragraph prg = new paragraph(title, font); spacingbefore = mm2px_height(spacingbefore); prg.setspacingbefore(prg.getleading() * -1 + prg.getfont().getsize() * 0.8f + spacingbefore); //prg.setspacingafter(spacingafter); this._document.add(prg); addspan(spacingafter); } /** * 添加标题。 * @param title 标题 * @param font 标题字体 * @param spacingbefore 标题前的空白(毫米) * @param spacingafter 标题后的空白(毫米) * @param alignment 标题的对齐方式(居中用element.align_center) * @throws documentexception * @throws ioexception */ protected void addtitle(string title, font font, float spacingbefore, float spacingafter, int alignment) throws documentexception, ioexception { paragraph prg = new paragraph(title, font); spacingbefore = mm2px_height(spacingbefore); prg.setspacingbefore(prg.getleading() * -1 + prg.getfont().getsize() * 0.8f + spacingbefore); prg.setalignment(alignment); //prg.setspacingafter(spacingafter); 改用下面的 addspan(spacingafter); this._document.add(prg); addspan(spacingafter); } /** * 添加段落文本。 * @param text 段落文本 * @param font 字体 * @param spacingbefore 段落前的空白(毫米) * @param leadingmult 文本行间距倍数 * @throws documentexception */ protected void addparagraphtext(string text, font font, float spacingbefore, float leadingmult) throws documentexception { addparagraphtext(text, font, spacingbefore, 0f, leadingmult); } /** * 添加段落文本。 * @param text 段落文本 * @param font 字体 * @param spacingbefore 段落前的空白(毫米) * @param spacingafter 段落后的空白(毫米) * @param leadingmult 文本行间距倍数 * @throws documentexception */ protected void addparagraphtext(string text, font font, float spacingbefore, float spacingafter, float leadingmult) throws documentexception { paragraph prg = new paragraph(text, font); //.trim() spacingbefore = mm2px_height(spacingbefore); //spacingafter = mm2px_height(spacingafter); prg.setleading(prg.getleading() * leadingmult); prg.setspacingbefore(prg.getleading() * -1f + prg.getfont().getsize() * 0.8f + spacingbefore); //prg.setspacingafter(spacingafter); //prg.setfirstlineindent(prg.getfont().getsize() * 2f); //首行缩进 prg.setalignment(element.align_left); //对齐方式 this._document.add(prg); addspan(spacingafter); } /** * 添加跨页后不再起作用的间隔。 * @param gap 间隔大小(毫米) * @throws documentexception */ protected void addspan(float gap) throws documentexception { pdfptable spantable = new pdfptable(1); spantable.settotalwidth(this._document.right() - this._document.left()); spantable.setlockedwidth(true); spantable.getdefaultcell().setborder(rectangle.no_border); spantable.setspacingafter(mm2px_height(gap)); //表后面的间隔,跨页之后不再起作用,要的就是这个效果 spantable.addcell(""); this._document.add(spantable); } /** * 添加每一章的头部文字。 * @param headerch 头部中文 * @param headeren 头部英文 * @throws documentexception * @throws ioexception */ protected void addchapterheader(string headerch, string headeren) throws documentexception, ioexception { font fontch = getfont(gdm.geturlstring(gdm.font_header_ch), gdm.font_size_header_ch, font.normal, gdm.color_gold); font fonten = getfont(gdm.geturlstring(gdm.font_header_en), gdm.font_size_header_en, font.normal, gdm.color_gold); phrase phrase = new phrase(); chunk chunkch = new chunk(headerch, fontch); phrase.add(chunkch); phrase.add(chunk.newline); chunk chunken = new chunk(headeren, fonten); phrase.add(chunken); paragraph prg = new paragraph(phrase); prg.setspacingafter(mm2px_width(gdm.spacing_after_header)); this._document.add(prg); } /** * 添加小节的头部图片 * @param imgfilename 含路径的图片文件名 * @throws malformedurlexception * @throws ioexception * @throws documentexception */ protected void addsectionheader(string imgfilename) throws malformedurlexception, ioexception, documentexception { paragraph prg = new paragraph(""); prg.setleading(0); this._document.add(prg);//在新开页中,上面段落的行间距会影响图片的位置 float width = gdm.page_width - gdm.margin_left - gdm.margin_right; float height = gdm.height_sectionheader; addimage(imgfilename, width, height); } /** * 添加图片。 * @param imgfilename 含路径的图片文件名 * @param width 图片宽度(毫米) * @param height 图片高度(毫米) * @throws malformedurlexception * @throws ioexception * @throws documentexception */ protected void addimage(string imgfilename, float width, float height) throws malformedurlexception, ioexception, documentexception { image img = image.getinstance(imgfilename); addimage(img, width, height); } /** * 添加图片。 * @param imgbyte 图片内存数组 * @param width 图片宽度(毫米) * @param height 图片高度(毫米) * @throws malformedurlexception * @throws ioexception * @throws documentexception */ protected void addimage(byte[] imgbyte, float width, float height) throws malformedurlexception, ioexception, documentexception { image img = image.getinstance(imgbyte); addimage(img, width, height); } /** * 添加图片。 * @param img 图片 * @param width 图片宽度(毫米) * @param height 图片高度(毫米) * @throws documentexception */ private void addimage(image img, float width, float height) throws documentexception { img.setalignment(image.align_left); width = mm2px_width(width); height = mm2px_height(height); img.scaleabsolute(width, height); this._document.add(img); } /** * 在指定位置添加图片。 * @param imgfilename 含路径的图片文件名 * @param width 图片宽度(毫米) * @param height 图片高度(毫米) * @param xpoint 距左边位置(毫米) * @param ypoint 距底边位置(毫米) * @throws malformedurlexception * @throws ioexception * @throws documentexception */ protected void addimageonsplocation(string imgfilename, float width, float height, float xpoint, float ypoint) throws malformedurlexception, ioexception, documentexception { image img = image.getinstance(imgfilename); img.setalignment(image.align_left); width = mm2px_width(width); height = mm2px_height(height); img.scaleabsolute(width, height); xpoint = mm2px_width(xpoint); ypoint = mm2px_height(ypoint); img.setabsoluteposition(xpoint, ypoint); this._document.add(img); } /** * 画线。 * @param beginx 开始x坐标(毫米) * @param beginy 开始y坐标(毫米) * @param endx 终止x坐标(毫米) * @param endy 终止y坐标(毫米) * @param linewidth * @param color */ protected void drawlint(float beginx, float beginy, float endx, float endy, float linewidth, basecolor color) { pdfcontentbyte cb = _writer.getdirectcontent(); cb.setlinewidth(linewidth); cb.setcolorstroke(color); beginx = mm2px_width(beginx); beginy = mm2px_height(beginy); endx = mm2px_width(endx); endy = mm2px_height(endy); cb.moveto(beginx, beginy); cb.lineto(endx, endy); cb.stroke(); } /** * 添加新的页面 */ protected void newpage() { this._document.newpage(); //this._writer.setpageempty(false); //fasle-页内容为空依然显示; true-页内容为空不会显示 } /** * 获取字体。 * @param fontname 字体名称(含路径) * @param fontsize 字体大小 * @param fontstyle 字体风格 * @param color 字体颜色 * @return 字体 * @throws documentexception * @throws ioexception */ public static font getfont(string fontname, float fontsize, int fontstyle, basecolor color) throws documentexception, ioexception { basefont bfont = basefont.createfont(fontname, basefont.identity_h, basefont.not_embedded); return new font(bfont, fontsize, fontstyle, color); } /** * 像素到毫米的转换(宽度) * @param px 横向像素 * @return */ public static float px2mm_width(float px) { return px * gdm.page_width / pagesize.a4.getwidth(); } /** * 毫米到像素的转换(宽度) * @param mm 横向毫米 * @return */ public static float mm2px_width(float mm) { return mm * pagesize.a4.getwidth() / gdm.page_width; //a4纸宽210毫米 } /** * 毫米到像素的转换(高度) * @param mm 纵向毫米 * @return */ public static float mm2px_height(float mm) { return mm * pagesize.a4.getheight() / gdm.page_height; //a4纸高297毫米 } /** * 添加法律声明、我们的观点、假设和依据、资产配置策略。 * @version 2017-03-30 * @param segments 文字或图片 * @param font 字体 * @param spacingbefore 段落前的空白(毫米) * @param leadingmult 行间距 * @throws malformedurlexception * @throws ioexception * @throws documentexception */ protected void addpdfword(object[] segments, font font, float spacingbefore, float leadingmult) throws malformedurlexception, ioexception, documentexception { for(object obj : segments) { if(obj instanceof byte[]) { image img = image.getinstance((byte[])obj); addimagetab(img); } else if(obj instanceof string) { addparagraphtext((string)obj, font, spacingbefore, px2mm_height(font.getsize()) * leadingmult, leadingmult); } } } /** * 以表格的方式添加图片。 * @version 2017-04-19 * @param img 图片 * @throws documentexception */ protected void addimagetab(image img) throws documentexception { float imgwidth = img.getwidth(); float imgheight = img.getheight(); float docwidth = this._document.right() - this._document.left(); float docheight = this._document.top() - this._document.bottom() - 5f * 2; float scalepercent_w = 100f; if(imgwidth > docwidth) scalepercent_w = docwidth * 100f / imgwidth; float scalepercent_h = 100f; if(imgheight > docheight) scalepercent_h = docheight * 100f / imgheight; float scalepercent = math.min(scalepercent_w, scalepercent_h); float fixedheight = imgheight * scalepercent / 100f; img.setalignment(image.align_left); img.scalepercent(scalepercent); pdfptable table = new pdfptable(1); table.setwidthpercentage(100f); pdfpcell imgcell = new pdfpcell(img); imgcell.setpadding(0f); imgcell.setfixedheight(fixedheight); imgcell.setborder(rectangle.no_border); table.addcell(imgcell); table.sethorizontalalignment(element.align_center); table.setspacingafter(5f); table.setspacingbefore(5f); table.keeprowstogether(0); this._document.add(table); } /** * 根据所在区域的宽高对图片进行不变形缩放。 * @param imgbyte 图片 * @param scalewidth 所在区域宽度 * @param scaleheight 所在区域高度 * @return * @throws badelementexception * @throws malformedurlexception * @throws ioexception */ protected image scaledimage(byte[] imgbyte, float scalewidth, float scaleheight) throws badelementexception, malformedurlexception, ioexception { image img = image.getinstance(imgbyte); float imgwidth = img.getwidth(); float imgheight = img.getheight(); float scalepercent_w = 100f; if(imgwidth > scalewidth) scalepercent_w = scalewidth * 100f / imgwidth; float scalepercent_h = 100f; if(imgheight > scaleheight) scalepercent_h = scaleheight * 100f / imgheight; float scalepercent = math.min(scalepercent_w, scalepercent_h); img.setalignment(image.align_left); img.scalepercent(scalepercent); return img; } /** * 获取文档可操作区域的宽度(像素)。 * @return */ protected float getdocwidth() { return this._document.right() - this._document.left(); } }
补充:java动态生成pdf含表格table和 合并两个pdf文件功能
1.首先一样需要maven依赖包:
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf --> <dependency> <groupid>com.itextpdf</groupid> <artifactid>itextpdf</artifactid> <version>5.5.10</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>
2.废话不多说,上代码,直接拿去运行测试:
public static void test1(){//生成pdf basefont bf; font font = null; try { bf = basefont.createfont( "stsong-light", "unigb-ucs2-h", basefont.not_embedded);//创建字体 font = new font(bf,12);//使用字体 } catch (exception e) { e.printstacktrace(); } document document = new document(); try { pdfwriter.getinstance(document, new fileoutputstream("e:/测试.pdf")); document.open(); document.add(new paragraph("就是测试下",font));//引用字体 document.add(new paragraph("真的测试下",font));//引用字体 float[] widths = {25f,25f,25f };// 设置表格的列宽和列数 默认是4列 pdfptable table = new pdfptable(widths);// 建立一个pdf表格 table.setspacingbefore(20f); table.setwidthpercentage(100);// 设置表格宽度为100% pdfpcell cell = null; cell = new pdfpcell(new paragraph("姓名",font));// cell.setbackgroundcolor(basecolor.light_gray); cell.sethorizontalalignment(element.align_center); table.addcell(cell); cell = new pdfpcell(new paragraph("性别",font));// cell.setbackgroundcolor(basecolor.light_gray); cell.sethorizontalalignment(element.align_center); table.addcell(cell); cell = new pdfpcell(new paragraph("身份证号",font));// cell.setbackgroundcolor(basecolor.light_gray); cell.sethorizontalalignment(element.align_center); table.addcell(cell); //以下代码的作用是创建100行数据,其中每行有四列,列依次为 编号 姓名 性别 备注 for (int i = 1; i <=10; i++) { //设置编号单元格 pdfpcell cell11=new pdfpcell(new paragraph("aa名媛",font)); pdfpcell cell22=new pdfpcell(new paragraph("bb女",font)); pdfpcell cell33=new pdfpcell(new paragraph("cc花姑娘",font)); //单元格水平对齐方式 cell11.sethorizontalalignment(element.align_center); //单元格垂直对齐方式 cell11.setverticalalignment(element.align_center); cell22.sethorizontalalignment(element.align_center); cell22.setverticalalignment(element.align_center); cell33.sethorizontalalignment(element.align_center); cell33.setverticalalignment(element.align_center); table.addcell(cell11); table.addcell(cell22); table.addcell(cell33); } document.add(table); document.close(); } catch (exception e) { system.out.println("file create exception"); } }
以下是合并多个pdf文件功能程序,上代码:
//*********合并 pdffilenames为文件路径数组,targetfilename为目标pdf路径 public static void combinpdf(string[] pdffilenames, string targetfilename) throws exception { pdfreader reader = null; document doc = new document(); pdfcopy pdfcopy = new pdfcopy(doc, new fileoutputstream(targetfilename)); int pagecount = 0; doc.open(); for (int i = 0; i < pdffilenames.length; ++i) { system.out.println(pdffilenames[i]); reader = new pdfreader(pdffilenames[i]); pagecount = reader.getnumberofpages(); for (int j = 1; j <= pagecount; ++j) { pdfcopy.addpage(pdfcopy.getimportedpage(reader, j)); } } doc.close(); }
这里附上测试程序:
public static void main(string[] args) throws interruptedexception { string filltemplate1 = "e:/测试.pdf"; string filltemplate2 = "e:/测试.pdf"; string[] st = {filltemplate1,filltemplate2}; try { combinpdf(st,"e:/合并.pdf"); } catch (exception e) { e.printstacktrace(); } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。