using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.Text;
using System.Data;
using System;
using System.Web;
public class CreatePDF
{
private static CreatePDF instance;
public static CreatePDF GetInstance()
{
if (instance == null)
{
instance = new CreatePDF();
}
return instance;
}
private static Document doc;
private static BaseFont bf = BaseFont.CreateFont(@"C://Windows/Fonts/simsun.ttc,0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
//四种字体
private static Font fontBig = new Font(bf, 20, Font.BOLD);
private static Font fontMiddle = new Font(bf, 15, Font.BOLD);
private static Font fontSmall = new Font(bf, 13, Font.BOLD);
private static Font fontSmallNoBold = new Font(bf, 13);
private static float IndentationLeft = 50;//距左边距
//如果要传参数进来,可自定义
public void GeneratePDF(string fileName,string filePath)
{
doc = new Document(PageSize.A4);
try
{
//MemoryStream ms2 = new MemoryStream();
//string fileName = string.Format("数据_{0}.pdf", DateTime.Now.ToString("yyyyMMddHHmmss"));
//string filePath = string.Format("{0}/Resource/{1}", AppDomain.CurrentDomain.BaseDirectory, fileName);
FileStream fs = new FileStream(filePath, FileMode.Open);//创建临时文件,到时生成好后删除
PdfWriter writer = PdfWriter.GetInstance(doc, fs);
writer.CloseStream = false;//把doc内容写入流中
doc.Open();
//核心操作
//CreateEmptyRow(1);//生成一行空行
//CreateLine();//生成一条下横线
//AddHeaderTitleContent("表10 已安装工程量明细表");//添加表头
//CreateEmptyRow(1);//生成一行空行
//AddPartnerContent("工程名称", "建设名称", "施工名称", "监理名称");//添加合作单位
//AddPageNumberContent();//添加页码
//CreateEmptyRow(1);//生成一行空行
//#region 生成表格数据
//PdfPTable table = new PdfPTable(6);//6列的table
////添加表格列头
//table.SetTotalWidth(new float[] { 50, 200, 60, 60, 100, 100 });
//table.AddCell(GetPdfCell("序号", fontSmallNoBold, Element.ALIGN_CENTER));
//table.AddCell(GetPdfCell("工程量名称", fontSmallNoBold, Element.ALIGN_CENTER));
//table.AddCell(GetPdfCell("单位", fontSmallNoBold, Element.ALIGN_CENTER));
//table.AddCell(GetPdfCell("数量", fontSmallNoBold, Element.ALIGN_CENTER));
//table.AddCell(GetPdfCell("安装地点、路段", fontSmallNoBold, Element.ALIGN_CENTER));
//table.AddCell(GetPdfCell("备注", fontSmallNoBold, Element.ALIGN_CENTER));
//int emptyRow = 20;//如果table的行数小于20行,那么剩余部分显示空白行
//#region 构造数据源
//DataTable tableSource = new DataTable();
//tableSource.Columns.Add(new DataColumn("aa"));
//tableSource.Columns.Add(new DataColumn("bb"));
//tableSource.Columns.Add(new DataColumn("cc"));
//tableSource.Columns.Add(new DataColumn("dd"));
//tableSource.Columns.Add(new DataColumn("ee"));
//for (int i = 0; i < 15; i++)
//{
// DataRow row = tableSource.NewRow();
// row["aa"] = "aa";
// row["bb"] = "bb";
// row["cc"] = "cc";
// row["dd"] = "dd";
// row["ee"] = "ee";
// tableSource.Rows.Add(row);
//}
//#endregion
//if (tableSource.Rows.Count > 0)
//{
// emptyRow = emptyRow - tableSource.Rows.Count;//如果为负数,说明不需要生成空白行
// for (int i = 0; i < tableSource.Rows.Count; i++)
// {
// DataRow row = tableSource.Rows[i];
// table.AddCell(GetPdfCell((i + 1).ToString(), fontSmallNoBold, Element.ALIGN_CENTER));
// table.AddCell(GetPdfCell(row["aa"].ToString(), fontSmallNoBold, Element.ALIGN_CENTER));
// table.AddCell(GetPdfCell(row["bb"].ToString(), fontSmallNoBold, Element.ALIGN_CENTER));
// table.AddCell(GetPdfCell(row["cc"].ToString(), fontSmallNoBold, Element.ALIGN_CENTER));
// table.AddCell(GetPdfCell(row["dd"].ToString(), fontSmallNoBold, Element.ALIGN_CENTER));
// table.AddCell(GetPdfCell(row["ee"].ToString(), fontSmallNoBold, Element.ALIGN_CENTER));
// }
//}
//if (emptyRow > 0)//说明数据源不足20行
//{
// for (int i = 0; i < emptyRow; i++)
// {
// table.AddCell(GetPdfCell(((20 - emptyRow) + i + 1).ToString(), fontSmallNoBold, Element.ALIGN_CENTER));
// table.AddCell(GetPdfCell("", fontSmallNoBold, Element.ALIGN_CENTER));
// table.AddCell(GetPdfCell("", fontSmallNoBold, Element.ALIGN_CENTER));
// table.AddCell(GetPdfCell("", fontSmallNoBold, Element.ALIGN_CENTER));
// table.AddCell(GetPdfCell("", fontSmallNoBold, Element.ALIGN_CENTER));
// table.AddCell(GetPdfCell("", fontSmallNoBold, Element.ALIGN_CENTER));
// }
//}
//doc.Add(table);
//#endregion
//添加N行空行
CreateEmptyRow(1);//生成一行空行
#region 添加水印
string waterMarkName = "经度:无 纬度:无 地址:无 验收负责人:无";
string waterMarkAddr = "广州市天河区";
if (!string.IsNullOrEmpty(waterMarkAddr))
{
waterMarkName = string.Format("经度:{0} 纬度:{1} 地址:{2} 验收负责人:{3}", "113.211", "23.211", waterMarkAddr, "张三");
}
#endregion
doc.Close();
MemoryStream ms = new MemoryStream();
if (fs != null)
{
byte[] bytes = new byte[fs.Length];//定义一个长度为fs长度的字节数组
fs.Read(bytes, 0, (int)fs.Length);//把fs的内容读到字节数组中
ms.Write(bytes, 0, bytes.Length);//把字节内容读到流中
fs.Flush();
fs.Close();
}
MemoryStream waterMS = SetWaterMark(ms, filePath, waterMarkName);//先生成水印,再删除临时文件
if (File.Exists(filePath))//判断临时文件是否存在,如果存在则删除
{
File.Delete(filePath);
GC.Collect();//回收垃圾
}
//SendFile(fileName, waterMS);//把PDF文件发送回浏览器
FileStream savefs = new FileStream(filePath, FileMode.Create);
BinaryWriter w = new BinaryWriter(savefs);
w.Write(waterMS.ToArray());
savefs.Close();
waterMS.Close();
}
catch (DocumentException ex)
{
throw new Exception(ex.Message);
}
}
#region 生成一条横线
private static void CreateLine()
{
PdfPTable table = new PdfPTable(1);//一个单元格的
table.TotalWidth = 500;
PdfPCell cell = new PdfPCell();
cell.BorderWidthBottom = 0.5f;
table.AddCell(cell);
doc.Add(table);
}
#endregion
#region 生成N行空白行
private static void CreateEmptyRow(int emptyRowNum)
{
for (int i = 0; i < emptyRowNum; i++)
{
doc.Add(new Paragraph(" "));
}
}
#endregion
#region 生成标题
private static void AddHeaderTitleContent(string content)
{
Paragraph p = new Paragraph(content, fontMiddle);
p.IndentationLeft = IndentationLeft;//距离左边距
doc.Add(p);
}
#endregion
#region 生成合作单位
private static void AddPartnerContent(string stationName, string constructUnit, string buildUnit, string supervisionUnit)
{
fontMiddle.SetStyle(Font.UNDERLINE);//文字下划线
IndentationLeft = IndentationLeft + 10;
Paragraph content = new Paragraph();
content.IndentationLeft = IndentationLeft;
Chunk chunkName = new Chunk("单项或单位工程名称:", fontSmallNoBold);
Chunk chunkText = new Chunk(GetEmptyString(25, stationName), fontMiddle);
content.Add(0, chunkName);
content.Add(1, chunkText);
content.Alignment = 3;
doc.Add(content);
content = new Paragraph();
content.IndentationLeft = IndentationLeft;
chunkName = new Chunk("建设单位名称:", fontSmallNoBold);
chunkText = new Chunk(GetEmptyString(30, constructUnit), fontMiddle);
content.Add(0, chunkName);
content.Add(1, chunkText);
content.Alignment = 3;
doc.Add(content);
content = new Paragraph();
content.IndentationLeft = IndentationLeft;
chunkName = new Chunk("施工单位名称:", fontSmallNoBold);
chunkText = new Chunk(GetEmptyString(30, buildUnit), fontMiddle);
content.Add(0, chunkName);
content.Add(1, chunkText);
content.Alignment = 3;
doc.Add(content);
content = new Paragraph();
content.IndentationLeft = IndentationLeft;
chunkName = new Chunk("监理单位名称:", fontSmallNoBold);
chunkText = new Chunk(GetEmptyString(30, supervisionUnit), fontMiddle);
content.Add(0, chunkName);
content.Add(1, chunkText);
content.Alignment = 3;
doc.Add(content);
}
//居中显示内容
private static string GetEmptyString(int maxlength, string text)
{
int padding = (maxlength - text.Length * 2) / 2;
string empty = string.Empty;
for (int i = 0; i < padding; i++)
{
empty += " ";
}
return string.Format("{0}{1}{0}", empty, text);
}
#endregion
#region 生成页码
private static void AddPageNumberContent()
{
var content = new Paragraph("共 页 第 页", fontSmall);
content.IndentationRight = IndentationLeft + 20;
content.Alignment = 2; //居左
doc.Add(content);
}
#endregion
#region 生成单元格
private static PdfPCell GetPdfCell(string content, Font font, int horizontalAlignment)
{
PdfPCell cell = new PdfPCell(new Paragraph(content, font));
cell.HorizontalAlignment = horizontalAlignment;//水平位置
cell.VerticalAlignment = Element.ALIGN_CENTER;//垂直居中
cell.MinimumHeight = 20;//单元格的最小高度
return cell;
}
#endregion
#region 生成水印
private static MemoryStream SetWaterMark(MemoryStream ms, string filePath, string waterMarkName, string waterMarkAddr = null)
{
MemoryStream msWater = new MemoryStream();
PdfReader pdfReader = null;
PdfStamper pdfStamper = null;
try
{
pdfReader = new PdfReader(filePath);
pdfStamper = new PdfStamper(pdfReader, msWater);
int total = pdfReader.NumberOfPages + 1;//获取PDF的总页数
iTextSharp.text.Rectangle psize = pdfReader.GetPageSize(1);//获取第一页
float width = psize.Width;//PDF页面的宽度,用于计算水印倾斜
float height = psize.Height;
PdfContentByte waterContent;
BaseFont basefont = BaseFont.CreateFont(@"C:\WINDOWS\Fonts\SIMFANG.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
PdfGState gs = new PdfGState();
for (int i = 1; i < total; i++)
{
waterContent = pdfStamper.GetOverContent(i);//在内容上方加水印
//透明度
waterContent.SetGState(gs);
//开始写入文本
waterContent.BeginText();
waterContent.SetColorFill(BaseColor.RED);
waterContent.SetFontAndSize(basefont, 18);
waterContent.SetTextMatrix(0, 0);
if (waterMarkAddr == null || waterMarkAddr == "")
{
waterContent.ShowTextAligned(Element.ALIGN_CENTER, waterMarkName, width / 2, height / 2, 55);
}
else
{
waterContent.ShowTextAligned(Element.ALIGN_CENTER, waterMarkName, width / 2, height / 2 + 100, 55);
waterContent.ShowTextAligned(Element.ALIGN_CENTER, waterMarkAddr, width / 2, height / 2 - 100, 55);
}
waterContent.EndText();
}
}
catch (Exception)
{
return ms;
}
finally
{
if (pdfStamper != null)
pdfStamper.Close();
if (pdfReader != null)
pdfReader.Close();
}
return msWater;
}
#endregion
//-----------------------发送PDF文件回浏览器端----------------------
public static void SendFile(string fileName, MemoryStream ms, Encoding encoding = null)
{
fileName = (fileName + "").Replace(" ", "");
encoding = encoding ?? Encoding.UTF8;
if (ms != null && !string.IsNullOrEmpty(fileName))
{
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.Clear();
response.Charset = encoding.BodyName;// "utf-8";
if (!HttpContext.Current.Request.UserAgent.Contains("Firefox") && !HttpContext.Current.Request.UserAgent.Contains("Chrome"))
{
fileName = HttpUtility.UrlEncode(fileName, encoding);
}
response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
//为了解决打开,导出NPOI生成的xlsx文件时,提示发现不可读取内容。
if (!(fileName + "").ToLower().EndsWith(".xlsx"))
{
response.AddHeader("Content-Type", "application/octet-stream");
response.BinaryWrite(ms.GetBuffer());
}
else
{
response.BinaryWrite(ms.ToArray());
}
ms.Close();
ms = null;
response.Flush();
response.End();
}
}
}