前言
最近公司一直使用iText開發PDF報表,使用一段時間之后發現iText這個類庫雖然是龐大無比,但作為程序猿我們不需要知道所有的類和方法,我們只需要知道如何使用即可。
所以這篇文章就是告訴大家如何快速的使用iTextSharp(iText .net版本)進行開發。
iTextSharp開發步驟
快速開發之前,我們先了解以下4個類:
class | 所代表的含義 |
Paragraph | 報表中的文本 |
Image | 報表中的圖片 |
PdfPTable | 表格 |
PdfPCell | 單元格 |
知道這4個類之后就是開發的步驟了:
1. 往單元格PdfPCell類中添加內容。
2.將單元格PdfPCell添加到PdfPTable。
3.將表格PdfPTable添加到Document。
在以上的步驟中最重要的就是第一步也就是往PdfPCell中添加內容,而PdfPCell中的內容又可以分為以下三種情況:
文本 | Paragraph |
圖片 | Image |
表格 | PdfPTable |
接下來我們就直奔主題,看是如何往PdfPCell添加內容。因為報表需要數據,所以我就從百度分辨率統計獲取了一些數據,下面是這個網址的截圖:
往PdfPCell添加文本
文本由Paragraph來表示,在添加之前還要注意一下字體的問題,因為我們用的是中文字體,如果用默認英文字體渲染則會亂碼,所以我們要先定義中文字體:
BaseFont BF_Light = BaseFont.CreateFont(@"C:\Windows\Fonts\simsun.ttc,0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
字體定義完之后下面就添加文本:
//要設置字體和大小 p = new Paragraph(fields[i], new Font(BF_Light, 13)); cell = new PdfPCell(p); //設置cell屬性 //cell.Border = Rectangle.NO_BORDER; if (rowNum == 0) { cell.BackgroundColor = BaseColor.GRAY; } if (i == mainColumn - 1) { cell.HorizontalAlignment = Element.ALIGN_RIGHT; } //添加單元格 table.AddCell(cell);
其實添加很簡單,就是最上面兩行代碼,而對PdfPCell屬性設置的代碼一般會比較多,因為我們一般要設置其背景色,水平對其,還有邊框Border等。
往PdfPCell添加圖片和表格
在大家了解怎么往PdfPCell添加完文本之后,添加圖片和表格就簡單很多了,就是將Image和PdfPTable作為PdfPCell的構造器參數傳入即可:
//圖片 Image image = Image.GetInstance(imagePath); cell = new PdfPCell(image, true); table.AddCell(cell); //表格 PdfPTable baseTable = GetBaseTable(); cell = new PdfPCell(baseTable); table.AddCell(cell);
以下就是效果圖:
iTextSharp畫圖
通過以上PdfPCell的操作,大家就可以實現一些比較常見的PDF報表,現在我們更進一步實現一下的效果:
這里就必須用到畫圖,畫圖用的就是PdfContentByte類,這個就類似於畫板,我們可以直接在上面畫直線和文本:
//畫線 canvas.SaveState(); canvas.SetLineWidth(2f); canvas.MoveTo(100, 100); canvas.LineTo(200, 200); canvas.Stroke(); canvas.RestoreState(); //文本 ColumnText.ShowTextAligned(canvas, Element.ALIGN_RIGHT, new Phrase("JulyLuo測試", new Font(BF_Light, 10)), 100, 20, 0);
這里要注意的是,無論是畫線還是文本我們都需要坐標,而且在畫線的時候,要將具體的代碼放在SaveState和RestoreState中間,這樣就不會導致畫圖狀態的紊亂。
如果我們希望將上圖畫在一個單元格中,但我們知道畫圖需要坐標,而在PdfPCell中是坐標沒有暴露出來,所以這里我們需要iTextSharp中的接口:IPdfPCellEvent
public void CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases)
這個接口的意思就是在單元格添加到文檔之后暴露的方法。很明顯,通過postion參數我們可以獲取坐標,canvases參數可以獲取畫板。
所以要畫圖就創建一個實現接口IPdfPCellEvent的類,然后在CellLayout方法中畫線和文本:
public void CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) { PdfContentByte cb = canvases[PdfPTable.BACKGROUNDCANVAS]; PdfContentByte cbline = canvases[PdfPTable.LINECANVAS]; cbline.SaveState(); cb.SaveState(); ………… cb.SetLineWidth(0.4f); cbline.SetLineWidth(0.4f); //y 軸 cb.MoveTo(leftX, bottomY); cb.LineTo(leftX, topY); cb.Stroke(); //y 軸突出的短橫線 float yAxiseTextLinetWidth = 3f; float yAxisTextSpaceAdjust = 2.5f; for (float y = yScaleNum; y < yMax; y += yScaleNum) { float yPoint = bottomY + (yScale * y); cb.MoveTo(leftX, yPoint); cb.LineTo(leftX - yAxiseTextLinetWidth, yPoint); cb.Stroke(); } //y 軸文本 for (float y = yScaleNum; y < yMax; y += yScaleNum) { float yPoint = bottomY + (yScale * y); ColumnText.ShowTextAligned(cb, Element.ALIGN_RIGHT, new Phrase(string.Format("{0}%", y), new Font(BF_Light, 5)), leftX - yAxiseTextLinetWidth, yPoint - yAxisTextSpaceAdjust, 0); } //x 軸 cb.MoveTo(leftX, bottomY); cb.LineTo(righX, bottomY); cb.Stroke(); ……… cb.Stroke(); cb.RestoreState(); cbline.RestoreState(); }
最后將這個類和對應的PdfPCell關聯起來:
//畫圖的類,和cell關聯 ResolutionChart chart = new ResolutionChart(fileName, yMax, yScale); cell.CellEvent = chart;
以下就是效果圖: