java 后端生成pdf模板合并单元格表格的案例
这里只放部分片段的代码
java中使用二维数组生成表格非常方便,但是每一维的数组都需要排好序,而且,在java中所谓的二维数组,三维数组等,其实都是多个一维数组组成的
/** *添加子女教育规划表。 *@paramname子女姓名 *@parameducationItems某个孩子的教育规划的二维数组,每列依次是:学程阶段、年数、费用支出(元)/年、年增长率 *@paramspacing *@throwsDocumentException *@throwsIOException */ privatevoidaddEducationTable(Stringname,String[][]educationItems,floatspacing)throwsDocumentException,IOException { addParagraphText(name+"的教育支出规划如下:",getMainTextFont(),0,SPACING_5,LEADING_MULT);//标题字段 //以下是表头 float[]colWidth=newfloat[]{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开始计数) PdfPTabletable=tableTemplate(educationItems,colWidth,colName,colAlignment,colPaddingLeft,colPaddingRight,colFont);//生成表格 table.setSpacingAfter(mm2px_height(spacing)); this._document.add(table);//生成到PDF去,代码就不贴了 } /** *@paramitems二维数组表示的表 *@paramcolWidth各列的宽度(像素) *@paramcolName各列的名称 *@paramcolAlignment各列的水平对齐方式 *@paramcolPaddingLeft各列的左padding *@paramcolPaddingRight各列的右padding *@paramcolFont各列的字体 *@return *@throwsDocumentException *@throwsIOException */ privatePdfPTabletableTemplates(String[][]items,float[]colWidth,String[]colName,int[]colAlignment, float[]colPaddingLeft,float[]colPaddingRight,Font[]colFont)throwsDocumentException,IOException { PdfPTableintTable=newPdfPTable(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); /*********************************************************************************************/ /***********************************以下是表头标题栏*******************************************/ floatheaderHeight=mm2px_height(TABLE_HEADER_HEIGHT); intTable.getDefaultCell().setFixedHeight(headerHeight);//行高 intTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);//无边框 for(inti=0;if1;j--){ data[i][j]=data[i][j-1]; } data[i][f1]=tamp; } returndata; } /** *@return获取表头标题栏字体。 *@throwsDocumentException *@throwsIOException */ privatestaticFontgetTabHeaderTextFont()throwsDocumentException,IOException { returngetFont(GDM.getUrlString(GDM.FONT_SIMHEI),FONT_SIZE_TAB_HEADER_TEXT,Font.NORMAL,COLOR_TAB_HEADER_TEXT); } /** *@return获取单元格文字字体。 *@throwsDocumentException *@throwsIOException */ privatestaticFontgetTabCellTextFont()throwsDocumentException,IOException { returngetFont(GDM.getUrlString(GDM.FONT_SIMHEI),FONT_SIZE_TAB_CELL_TEXT,Font.NORMAL,GDM.COLOR_666666); } /** *@return获取标题字体。 *@throwsDocumentException *@throwsIOException */ privatestaticFontgetTitleFont()throwsDocumentException,IOException { returngetFont(GDM.getUrlString(GDM.FONT_HEADER_CH),FONT_SIZE_TITLE,Font.NORMAL,GDM.COLOR_333333); } /** *@return获取标题字体(小)。 *@throwsDocumentException *@throwsIOException */ privatestaticFontgetTitleFont_Small()throwsDocumentException,IOException { returngetFont(GDM.getUrlString(GDM.FONT_HEADER_CH),FONT_SIZE_TITLE-1f,Font.NORMAL,GDM.COLOR_333333); } /** *@return获取正文字体。 *@throwsDocumentException *@throwsIOException */ privatestaticFontgetMainTextFont()throwsDocumentException,IOException { returngetFont(GDM.getUrlString(GDM.FONT_NORMAL),FONT_SIZE_MAINTEXT,Font.NORMAL,GDM.COLOR_666666); }
加一个生成pdf常用的格式工具类
importjava.io.IOException; importjava.net.MalformedURLException; importcom.itextpdf.text.BadElementException; importcom.itextpdf.text.BaseColor; importcom.itextpdf.text.Chunk; importcom.itextpdf.text.Document; importcom.itextpdf.text.DocumentException; importcom.itextpdf.text.Element; importcom.itextpdf.text.Font; importcom.itextpdf.text.Image; importcom.itextpdf.text.PageSize; importcom.itextpdf.text.Paragraph; importcom.itextpdf.text.Phrase; importcom.itextpdf.text.Rectangle; importcom.itextpdf.text.pdf.BaseFont; importcom.itextpdf.text.pdf.ColumnText; importcom.itextpdf.text.pdf.PdfContentByte; importcom.itextpdf.text.pdf.PdfPCell; importcom.itextpdf.text.pdf.PdfPTable; importcom.itextpdf.text.pdf.PdfWriter; publicclassFinPlan { protectedDocument_document;//文档对象 protectedPdfWriter_writer;//pdf文档输出器 publicFinPlan(Documentdocument,PdfWriterwriter) { super(); this._document=document; this._writer=writer; } /** *像素到毫米的转换(高度) *@parampx纵向像素 *@return */ publicstaticfloatpx2mm_height(floatpx) { returnpx*GDM.PAGE_HEIGHT/PageSize.A4.getHeight(); } /** *在指定位置写入文字 *@paramtext需要写入的文字 *@paramxPoint距左边位置(毫米) *@paramyPoint距底边位置(毫米) */ protectedvoidwriteOnSpLocation(floatxPoint,floatyPoint,Stringtext,Fontfont) { PdfContentBytepcb=this._writer.getDirectContent(); xPoint=mm2px_width(xPoint); yPoint=mm2px_height(yPoint); Paragraphprg=newParagraph(text,font); ColumnText.showTextAligned(pcb,PdfContentByte.ALIGN_LEFT,prg,xPoint,yPoint,0); } /** *添加标题。 *@paramtitle标题 *@paramfont标题字体 *@paramspacingBefore标题前的空白(毫米) *@throwsDocumentException *@throwsIOException */ protectedvoidaddTitle(Stringtitle,Fontfont,floatspacingBefore)throwsDocumentException,IOException { addTitle(title,font,spacingBefore,0f); } /** *添加标题。 *@paramtitle标题 *@paramfont标题字体 *@paramspacingBefore标题前的空白(毫米) *@paramspacingAfter标题后的空白(毫米) *@throwsDocumentException *@throwsIOException */ protectedvoidaddTitle(Stringtitle,Fontfont,floatspacingBefore,floatspacingAfter)throwsDocumentException,IOException { Paragraphprg=newParagraph(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); } /** *添加标题。 *@paramtitle标题 *@paramfont标题字体 *@paramspacingBefore标题前的空白(毫米) *@paramspacingAfter标题后的空白(毫米) *@paramalignment标题的对齐方式(居中用Element.ALIGN_CENTER) *@throwsDocumentException *@throwsIOException */ protectedvoidaddTitle(Stringtitle,Fontfont,floatspacingBefore,floatspacingAfter,intalignment)throwsDocumentException,IOException { Paragraphprg=newParagraph(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); } /** *添加段落文本。 *@paramtext段落文本 *@paramfont字体 *@paramspacingBefore段落前的空白(毫米) *@paramleadingMult文本行间距倍数 *@throwsDocumentException */ protectedvoidaddParagraphText(Stringtext,Fontfont,floatspacingBefore,floatleadingMult)throwsDocumentException { addParagraphText(text,font,spacingBefore,0f,leadingMult); } /** *添加段落文本。 *@paramtext段落文本 *@paramfont字体 *@paramspacingBefore段落前的空白(毫米) *@paramspacingAfter段落后的空白(毫米) *@paramleadingMult文本行间距倍数 *@throwsDocumentException */ protectedvoidaddParagraphText(Stringtext,Fontfont,floatspacingBefore,floatspacingAfter,floatleadingMult)throwsDocumentException { Paragraphprg=newParagraph(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); } /** *添加跨页后不再起作用的间隔。 *@paramgap间隔大小(毫米) *@throwsDocumentException */ protectedvoidaddSpan(floatgap)throwsDocumentException { PdfPTablespanTable=newPdfPTable(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); } /** *添加每一章的头部文字。 *@paramheaderCH头部中文 *@paramheaderEN头部英文 *@throwsDocumentException *@throwsIOException */ protectedvoidaddChapterHeader(StringheaderCH,StringheaderEN)throwsDocumentException,IOException { FontfontCH=getFont(GDM.getUrlString(GDM.FONT_HEADER_CH),GDM.FONT_SIZE_HEADER_CH,Font.NORMAL,GDM.COLOR_GOLD); FontfontEN=getFont(GDM.getUrlString(GDM.FONT_HEADER_EN),GDM.FONT_SIZE_HEADER_EN,Font.NORMAL,GDM.COLOR_GOLD); Phrasephrase=newPhrase(); ChunkchunkCH=newChunk(headerCH,fontCH); phrase.add(chunkCH); phrase.add(Chunk.NEWLINE); ChunkchunkEN=newChunk(headerEN,fontEN); phrase.add(chunkEN); Paragraphprg=newParagraph(phrase); prg.setSpacingAfter(mm2px_width(GDM.SPACING_AFTER_HEADER)); this._document.add(prg); } /** *添加小节的头部图片 *@paramimgFilename含路径的图片文件名 *@throwsMalformedURLException *@throwsIOException *@throwsDocumentException */ protectedvoidaddSectionHeader(StringimgFilename)throwsMalformedURLException,IOException,DocumentException { Paragraphprg=newParagraph(""); prg.setLeading(0); this._document.add(prg);//在新开页中,上面段落的行间距会影响图片的位置 floatwidth=GDM.PAGE_WIDTH-GDM.MARGIN_LEFT-GDM.MARGIN_RIGHT; floatheight=GDM.HEIGHT_SECTIONHEADER; addImage(imgFilename,width,height); } /** *添加图片。 *@paramimgFilename含路径的图片文件名 *@paramwidth图片宽度(毫米) *@paramheight图片高度(毫米) *@throwsMalformedURLException *@throwsIOException *@throwsDocumentException */ protectedvoidaddImage(StringimgFilename,floatwidth,floatheight)throwsMalformedURLException,IOException,DocumentException { Imageimg=Image.getInstance(imgFilename); addImage(img,width,height); } /** *添加图片。 *@paramimgByte图片内存数组 *@paramwidth图片宽度(毫米) *@paramheight图片高度(毫米) *@throwsMalformedURLException *@throwsIOException *@throwsDocumentException */ protectedvoidaddImage(byte[]imgByte,floatwidth,floatheight)throwsMalformedURLException,IOException,DocumentException { Imageimg=Image.getInstance(imgByte); addImage(img,width,height); } /** *添加图片。 *@paramimg图片 *@paramwidth图片宽度(毫米) *@paramheight图片高度(毫米) *@throwsDocumentException */ privatevoidaddImage(Imageimg,floatwidth,floatheight)throwsDocumentException { img.setAlignment(Image.ALIGN_LEFT); width=mm2px_width(width); height=mm2px_height(height); img.scaleAbsolute(width,height); this._document.add(img); } /** *在指定位置添加图片。 *@paramimgFilename含路径的图片文件名 *@paramwidth图片宽度(毫米) *@paramheight图片高度(毫米) *@paramxPoint距左边位置(毫米) *@paramyPoint距底边位置(毫米) *@throwsMalformedURLException *@throwsIOException *@throwsDocumentException */ protectedvoidaddImageOnSpLocation(StringimgFilename,floatwidth,floatheight,floatxPoint,floatyPoint)throwsMalformedURLException,IOException,DocumentException { Imageimg=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); } /** *画线。 *@parambeginX开始X坐标(毫米) *@parambeginY开始Y坐标(毫米) *@paramendX终止X坐标(毫米) *@paramendY终止Y坐标(毫米) *@paramlineWidth *@paramcolor */ protectedvoiddrawLint(floatbeginX,floatbeginY,floatendX,floatendY,floatlineWidth,BaseColorcolor) { PdfContentBytecb=_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(); } /** *添加新的页面 */ protectedvoidnewPage() { this._document.newPage(); //this._writer.setPageEmpty(false);//fasle-页内容为空依然显示;true-页内容为空不会显示 } /** *获取字体。 *@paramfontname字体名称(含路径) *@paramfontsize字体大小 *@paramfontstyle字体风格 *@paramcolor字体颜色 *@return字体 *@throwsDocumentException *@throwsIOException */ publicstaticFontgetFont(Stringfontname,floatfontsize,intfontstyle,BaseColorcolor)throwsDocumentException,IOException { BaseFontbfont=BaseFont.createFont(fontname,BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED); returnnewFont(bfont,fontsize,fontstyle,color); } /** *像素到毫米的转换(宽度) *@parampx横向像素 *@return */ publicstaticfloatpx2mm_width(floatpx) { returnpx*GDM.PAGE_WIDTH/PageSize.A4.getWidth(); } /** *毫米到像素的转换(宽度) *@parammm横向毫米 *@return */ publicstaticfloatmm2px_width(floatmm) { returnmm*PageSize.A4.getWidth()/GDM.PAGE_WIDTH;//A4纸宽210毫米 } /** *毫米到像素的转换(高度) *@parammm纵向毫米 *@return */ publicstaticfloatmm2px_height(floatmm) { returnmm*PageSize.A4.getHeight()/GDM.PAGE_HEIGHT;//A4纸高297毫米 } /** *添加法律声明、我们的观点、假设和依据、资产配置策略。 *@version2017-03-30 *@paramsegments文字或图片 *@paramfont字体 *@paramspacingBefore段落前的空白(毫米) *@paramleadingMult行间距 *@throwsMalformedURLException *@throwsIOException *@throwsDocumentException */ protectedvoidaddPdfWord(Object[]segments,Fontfont,floatspacingBefore,floatleadingMult)throwsMalformedURLException,IOException,DocumentException { for(Objectobj:segments) { if(objinstanceofbyte[]) { Imageimg=Image.getInstance((byte[])obj); addImageTab(img); } elseif(objinstanceofString) { addParagraphText((String)obj,font,spacingBefore,px2mm_height(font.getSize())*leadingMult,leadingMult); } } } /** *以表格的方式添加图片。 *@version2017-04-19 *@paramimg图片 *@throwsDocumentException */ protectedvoidaddImageTab(Imageimg)throwsDocumentException { floatimgWidth=img.getWidth(); floatimgHeight=img.getHeight(); floatdocWidth=this._document.right()-this._document.left(); floatdocHeight=this._document.top()-this._document.bottom()-5f*2; floatscalePercent_w=100f; if(imgWidth>docWidth)scalePercent_w=docWidth*100f/imgWidth; floatscalePercent_h=100f; if(imgHeight>docHeight)scalePercent_h=docHeight*100f/imgHeight; floatscalePercent=Math.min(scalePercent_w,scalePercent_h); floatfixedHeight=imgHeight*scalePercent/100f; img.setAlignment(Image.ALIGN_LEFT); img.scalePercent(scalePercent); PdfPTabletable=newPdfPTable(1); table.setWidthPercentage(100f); PdfPCellimgCell=newPdfPCell(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); } /** *根据所在区域的宽高对图片进行不变形缩放。 *@paramimgByte图片 *@paramscaleWidth所在区域宽度 *@paramscaleHeight所在区域高度 *@return *@throwsBadElementException *@throwsMalformedURLException *@throwsIOException */ protectedImagescaledImage(byte[]imgByte,floatscaleWidth,floatscaleHeight)throwsBadElementException,MalformedURLException,IOException { Imageimg=Image.getInstance(imgByte); floatimgWidth=img.getWidth(); floatimgHeight=img.getHeight(); floatscalePercent_w=100f; if(imgWidth>scaleWidth)scalePercent_w=scaleWidth*100f/imgWidth; floatscalePercent_h=100f; if(imgHeight>scaleHeight)scalePercent_h=scaleHeight*100f/imgHeight; floatscalePercent=Math.min(scalePercent_w,scalePercent_h); img.setAlignment(Image.ALIGN_LEFT); img.scalePercent(scalePercent); returnimg; } /** *获取文档可操作区域的宽度(像素)。 *@return */ protectedfloatgetDocWidth() { returnthis._document.right()-this._document.left(); } }
补充:java动态生成pdf含表格table和合并两个pdf文件功能
1.首先一样需要maven依赖包:
com.itextpdf itextpdf 5.5.10 com.itextpdf itext-asian 5.2.0
2.废话不多说,上代码,直接拿去运行测试:
publicstaticvoidtest1(){//生成pdf BaseFontbf; Fontfont=null; try{ bf=BaseFont.createFont("STSong-Light","UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);//创建字体 font=newFont(bf,12);//使用字体 }catch(Exceptione){ e.printStackTrace(); } Documentdocument=newDocument(); try{ PdfWriter.getInstance(document,newFileOutputStream("E:/测试.pdf")); document.open(); document.add(newParagraph("就是测试下",font));//引用字体 document.add(newParagraph("真的测试下",font));//引用字体 float[]widths={25f,25f,25f};//设置表格的列宽和列数默认是4列 PdfPTabletable=newPdfPTable(widths);//建立一个pdf表格 table.setSpacingBefore(20f); table.setWidthPercentage(100);//设置表格宽度为100% PdfPCellcell=null; cell=newPdfPCell(newParagraph("姓名",font));// cell.setBackgroundColor(BaseColor.LIGHT_GRAY); cell.setHorizontalAlignment(Element.ALIGN_CENTER); table.addCell(cell); cell=newPdfPCell(newParagraph("性别",font));// cell.setBackgroundColor(BaseColor.LIGHT_GRAY); cell.setHorizontalAlignment(Element.ALIGN_CENTER); table.addCell(cell); cell=newPdfPCell(newParagraph("身份证号",font));// cell.setBackgroundColor(BaseColor.LIGHT_GRAY); cell.setHorizontalAlignment(Element.ALIGN_CENTER); table.addCell(cell); //以下代码的作用是创建100行数据,其中每行有四列,列依次为编号姓名性别备注 for(inti=1;i<=10;i++){ //设置编号单元格 PdfPCellcell11=newPdfPCell(newParagraph("aa名媛",font)); PdfPCellcell22=newPdfPCell(newParagraph("bb女",font)); PdfPCellcell33=newPdfPCell(newParagraph("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(Exceptione){ System.out.println("filecreateexception"); } }
以下是合并多个pdf文件功能程序,上代码:
//*********合并pdfFilenames为文件路径数组,targetFileName为目标pdf路径 publicstaticvoidcombinPdf(String[]pdfFilenames,StringtargetFilename) throwsException{ PdfReaderreader=null; Documentdoc=newDocument(); PdfCopypdfCopy=newPdfCopy(doc,newFileOutputStream(targetFilename)); intpageCount=0; doc.open(); for(inti=0;i这里附上测试程序:
publicstaticvoidmain(String[]args)throwsInterruptedException{ StringfillTemplate1="E:/测试.pdf"; StringfillTemplate2="E:/测试.pdf"; String[]st={fillTemplate1,fillTemplate2}; try{ combinPdf(st,"E:/合并.pdf"); }catch(Exceptione){ e.printStackTrace(); } }以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。