ITextSharp是一个在C#平台下操作pdf的一个工具dll
但是,自从4.1.6版本之后的ITextSharp的license变成了AGPL,所以不能商用。所以说version 4.1.6就是目前为止可以商用的最新版本
所以让我们下载4.1.6版本的ITextSharp,然后把它加载到我们的工程之中来。
1. ITextSharp操作文本域
我们经常遇到这种需求:使用一个pdf模板,填充上数据,最后导出一个填充好数据的pdf
ITextSharp可以很好的解决这个问题,
第一步,先用Adobe Acrobat做好模板(具体步骤请自行google)
第二步,使用ITextSharp来填充模板中的文本域
这里,提供一个我自己写的共同方法
private void MakeEnPdf(string pdfTemplate, string tempFilePath, Dictionary<string, string> parameters)
{
PdfReader pdfReader = null;
PdfStamper pdfStamper = null;
try
{
//When the temp file already exists, delete it.
if (File.Exists(tempFilePath))
{
File.Delete(tempFilePath);
}
pdfReader = new PdfReader(pdfTemplate);
pdfStamper = new PdfStamper(pdfReader, new FileStream(tempFilePath, FileMode.Create));
// Get the collection of domain.
AcroFields pdfFormFields = pdfStamper.AcroFields;
//pdfFormFields.GenerateAppearances = false;
pdfStamper.FormFlattening = true;
// Set value for the required domain.
foreach (KeyValuePair<string, string> parameter in parameters)
{
if (pdfFormFields.Fields[parameter.Key] != null)
{
pdfFormFields.SetField(parameter.Key, parameter.Value);
}
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
pdfStamper.Close();
pdfReader.Close();
pdfStamper = null;
pdfReader = null;
}
}
其中, pdfTemplate是template的路径,tempFilePath是要生成的pdf的路径,parameters是一个词典,
使用这个共同方法可以参考如下代码
#region Create temporary pdf file without images
var tempGuid = Guid.NewGuid().ToString();
var tempFileName = "Product_Data_Sheet_template_2016_Base_" + tempGuid + ".pdf";
var tempFilePath = Path.Combine(tempUserFolder, tempFileName);
MakeEnPdf(pdfTemplate, tempFilePath, parameters);
#endregion
这个地方,相信大家都可以搜索到一个很好的网址 http://www.mikesdotnetting.com/article/87/itextsharp-working-with-images
基本的操作这里说的比较完全了,但是有一个方面他没有说到,就是: 在pdf的一个rectangle里面放置图片,这个地方我提供一下我的解决思路
首先要得到rectangle的位置信息及它的大小,提供一个类
public class CanvasContainerRectangle
{
public CanvasContainerRectangle(float startX, float startY, float rectWidth, float rectHeight)
{
this.StartX = startX;
this.StartY = startY;
this.RectWidth = rectWidth;
this.RectHeight = rectHeight;
}
public float StartX { get; set; }
public float StartY { get; set; }
public float RectWidth { get; set; }
public float RectHeight { get; set; }
}
我们在把图片放置在container里面的时候,需要把图片进行缩放,我们需要得到这个缩放的百分比
private float GetPercentage(float width, float height, CanvasContainerRectangle containerRect)
{
float percentage = 0;
if(height > width)
{
percentage = containerRect.RectHeight / height;
if(width * percentage > containerRect.RectWidth)
{
percentage = containerRect.RectWidth / width;
}
}
else
{
percentage = containerRect.RectWidth / width;
if(height * percentage > containerRect.RectHeight)
{
percentage = containerRect.RectHeight / height;
}
}
return percentage;
}
public class PdfImage
{
public PdfImage(string imageUrl, float fitWidth, float fitHeight, float absolutX, float absoluteY, bool scaleParent)
{
this.ImageUrl = imageUrl;
this.FitWidth = fitWidth;
this.FitHeight = fitHeight;
this.AbsoluteX = absolutX;
this.AbsoluteY = absoluteY;
this.ScaleParent = scaleParent;
}
public PdfImage(string imageUrl, float fitWidth, float fitHeight, float absolutX, float absoluteY, bool scaleParent, byte[] imgBytes)
{
this.ImageUrl = imageUrl;
this.FitWidth = fitWidth;
this.FitHeight = fitHeight;
this.AbsoluteX = absolutX;
this.AbsoluteY = absoluteY;
this.ScaleParent = scaleParent;
this.ImgBytes = imgBytes;
}
public string ImageUrl { get; set; }
public float FitWidth { get; set; }
public float FitHeight { get; set; }
public float AbsoluteX { get; set; }
public float AbsoluteY { get; set; }
public byte[] ImgBytes { get; set; }
public bool ScaleParent { get; set; }
public CanvasContainerRectangle ContainerRect { get; set; }
}
/// <summary>
/// Create a pdf with images putting
/// </summary>
/// <param name="tempFilePath">The source pdf file</param>
/// <param name="createdPdfPath">The destination pdf file which will be created</param>
/// <param name="pdfImages">Images list</param>
private void PutImages(string tempFilePath, string createdPdfPath, List<PdfImage> pdfImages)
{
PdfReader pdfReader = null;
PdfStamper pdfStamper = null;
try
{
pdfReader = new PdfReader(tempFilePath);
pdfStamper = new PdfStamper(pdfReader, new FileStream(createdPdfPath, FileMode.Create));
var pdfContentByte = pdfStamper.GetOverContent(1);
foreach(var pdfImage in pdfImages)
{
Uri uri = null;
Image img = null;
var imageUrl = pdfImage.ImageUrl;
//If imageUrl is a relative path, get the absolute path firstly
if (!imageUrl.StartsWith("http"))
{
//var absolutePath = Path.Combine(System.Web.HttpContext.Current.Server.MapPath(".."), imageUrl);
var absolutePath = System.Web.HttpContext.Current.Server.MapPath("..") + imageUrl;
uri = new Uri(absolutePath);
img = Image.GetInstance(uri);
}
else
{
//Get the image first, and then transfer it to ITextSharp image
if (pdfImage.ImgBytes != null)
{
img = Image.GetInstance(new MemoryStream(pdfImage.ImgBytes));
}
}
if(img != null)
{
if (pdfImage.ScaleParent)
{
var containerRect = pdfImage.ContainerRect;
float percentage = 0.0f;
percentage = GetPercentage(img.Width, img.Height, containerRect);
img.ScalePercent(percentage * 100);
pdfImage.AbsoluteX = (containerRect.RectWidth - img.Width * percentage) / 2 + containerRect.StartX;
pdfImage.AbsoluteY = (containerRect.RectHeight - img.Height * percentage) / 2 + containerRect.StartY;
}
else
{
img.ScaleToFit(pdfImage.FitWidth, pdfImage.FitHeight);
}
img.SetAbsolutePosition(pdfImage.AbsoluteX, pdfImage.AbsoluteY);
pdfContentByte.AddImage(img);
}
}
pdfStamper.FormFlattening = true;
}
catch(Exception ex)
{
throw ex;
}
finally
{
if (pdfStamper != null)
{
pdfStamper.Close();
}
if (pdfReader != null)
{
pdfReader.Close();
}
pdfStamper = null;
pdfReader = null;
}
}
我们在使用的时候,首先要把要加载的图片,做成PdfImage格式,然后调用PutImages方法,把这些图片加载到pdf之中
注意,我这里是把图片加载到rectangle的正中间位置,如果要到其他的位置,可以自己改一下PutImages函数