65.9K
CodeProject 正在变化。 阅读更多。
Home

另一个 PDFLib - 第 1 部分:显示文本和绘制图形

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.73/5 (20投票s)

2005年12月27日

LGPL3

1分钟阅读

viewsIcon

112366

downloadIcon

984

一个用于手动创建PDF文件的.NET库。

引言

PDF文件越来越受欢迎;在我们的应用程序中,我们可能需要一个库来操作这些PDF文件,而无需使用Acrobat SDK。虽然有这样的库可用,但我还是想自己创建一个。该库支持PDF对象内的Unicode和编码选择,以便我可以在PDF文档中自由使用中文字符。

该库是用C#编写的,需要.NET 2.0。

该项目的目标是实现PDF 1.6参考规范中指定的所有功能,并提供创建、读取和操作PDF文件的工具。这个库只是一个起点。

当前功能

  • 基本数据类型(数字、字符串、日期时间、数组、字典、流...)
  • 文件结构和文档结构
  • 路径构建和绘制
  • 图形状态
  • 变换矩阵
  • Form XObjects
  • 文本状态
  • 文本对象
  • Type 1字体
  • 来自Type 0 CIDFont的复合字体
  • 文档大纲和PageLables
  • ViewerPreferences

使用代码

  1. 坐标系:坐标在用户空间中指定
    • 原点位于页面的左下角;
    • X轴从左到右延伸,Y轴从下到上延伸;
    • 可以使用Page.UserUnit设置长度单位,默认值为1/72英寸。
  2. 字体和XObjects不能直接使用。它们需要添加到文档的资源字典中,并且每个字体/XObject都应与一个键关联,然后在页面内容中使用。

以下示例显示了此库的基本用法

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using AnotherPDFLib;
using AnotherPDFLib.PdfObjects;
using AnotherPDFLib.PdfText;
using AnotherPDFLib.PdfGraphics;
 
namespace AnotherPDFLibTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        PdfDocument pdfdoc;
        PdfPage page;
        string PageNumberFormat;

        private void buttonCreateDocument_Click(object sender, EventArgs e)
        {
            pdfdoc = new PdfDocument(PaperSize.A4);
            pdfdoc.DocumentInfo.Creator = Application.ExecutablePath;
            pdfdoc.DocumentInfo.Author = "Liu Junfeng";
            pdfdoc.Catalog.PageMode = PageMode.UseOutlines;

            PageLabelRange firstrange = 
                new PageLabelRange(0, NumberingStyle.RomanLowercase);
            PageLabelRange secondrange = 
                new PageLabelRange(3, NumberingStyle.ArabicDecimal);
            pdfdoc.PageLabels.Add(firstrange);
            pdfdoc.PageLabels.Add(secondrange);

            comboBoxFont.Items.Clear();
            AddFont(StandardFont.Courier);
            AddFont(StandardFont.Helvetica);
            AddFont(ChineseFont.AdobeSong);

            buttonNewPage_Click(null, null);

            numericUpDownX.Maximum = (decimal)pdfdoc.PageSize.Width;
            numericUpDownY.Maximum = (decimal)pdfdoc.PageSize.Height;
            numericUpDownX.Value = 100;
            numericUpDownY.Value = numericUpDownY.Maximum - 100;
        }

        void AddFont(PdfFont font)
        {
            string fontID = pdfdoc.AddFont(font);
            string fontItem = 
              fontID + "(" + font.BaseFont + ")";
            comboBoxFont.Items.Add(fontItem);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            PageNumberFormat = this.Text + " (Page {0})";
            comboBoxEncoding.Items.AddRange(
                new object[] 
                    { "ASCII", "GB2312", "GB18030", "UTF-16BE" });
            comboBoxEncoding.SelectedIndex = 0;

            //set PdfWriter formattings
            PdfWriter.ListDictionary = false;
            PdfWriter.ListContentStream = true;
        }

        private void comboBoxEncoding_SelectedIndexChanged(
                                       object sender, EventArgs e)
        {
            switch (comboBoxEncoding.SelectedItem.ToString())
            {
                case "ASCII":
                    break;
                case "GB2312":
                    ChineseFont.AdobeSong.Encoding = 
                         CMap.ChineseSimplified.GB_EUC_H;
                    break;
                case "GB18030":
                    ChineseFont.AdobeSong.Encoding = 
                         CMap.ChineseSimplified.GBK_EUC_H;
                    break;
                default:
                    ChineseFont.AdobeSong.Encoding = 
                         CMap.ChineseSimplified.UniGB_UTF16_H;
                    break;
            }
        }

        private void buttonSave_Click(object sender, EventArgs e)
        {
            try
            {
                string file = textBoxFile.Text;
                pdfdoc.Save(file);
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }
        }
        private void buttonNewPage_Click(object sender, EventArgs e)
        {
            if (pdfdoc == null)
            {
                MessageBox.Show("Document not created!");
                return;
            }
            page = pdfdoc.NewPage();
            
            //add outline item
            PdfOutlineItem outlineitem = new PdfOutlineItem();
            outlineitem.Title = "Page " + pdfdoc.PageCount;
            outlineitem.Dest = Destination.FitPage(page);
            pdfdoc.Outlines.Append(outlineitem);

            TextState ts = new TextState();
            //set page level TextState
            //...
            //page.Content.AddGraphicObject(ts);
            ShowPageNumber();
        }

 

        void ShowPageNumber()
        {
            this.Text = string.Format(PageNumberFormat, pdfdoc.PageCount);
        }

        private void buttonAddText_Click(object sender, EventArgs e)
        {
            if (pdfdoc == null)
            {
                MessageBox.Show("Document not created!");
                return;
            }
            if (comboBoxFont.SelectedIndex == -1)
            {
                MessageBox.Show("No font selected!");
                return;
            }
            double tx = (double)numericUpDownX.Value;
            double ty = (double)numericUpDownY.Value;
            string font = 
                comboBoxFont.SelectedItem.ToString().Split('(')[0];
            int size = (int)numericUpDownSize.Value;
            Encoding encoding = 
                Encoding.GetEncoding(comboBoxEncoding.Text);

            PdfText pdfText = new PdfText(encoding);
            pdfText.Begin();
            pdfText.TextState.Font = new TextFont(font, size);
            pdfText.TextState.RenderingMode = GetRenderMode();
            pdfText.TextState.LineHeight = (int)size * 1.5;
            pdfText.StartNewLine(tx, ty);
            //pdfText.TextMatrix = TMatrix.Translation(tx, ty);
            foreach (string line in richTextBox.Lines)
            {
                pdfText.ShowText(line);
                pdfText.StartNewLine();
            }
            pdfText.End();
            page.Content.Add(pdfText);
        }

        RenderMode GetRenderMode()
        {
            RenderMode mode = RenderMode.None;
            if (checkBoxFill.Checked)
            {
                mode &= RenderMode.Fill;
            }
            if (checkBoxStroke.Checked)
            {
                mode &= RenderMode.Stroke;
            }
            if (checkBoxClipPath.Checked)
            {
                mode &= RenderMode.ClipPath;
            }
            return mode;
        }

        private void buttonnDrawGraph_Click(object sender, EventArgs e)
        {
            Path path = new Path();
            //SubPath subpath = new SubPath(0, 0);
            //subpath.AddLine(200, 300);
            //path.AddSubPath(subpath);
            //path.AddRectangle(200, 300, 100, 100);
            SubPath subpath = new SubPath(120, 800);
            subpath.LineTo(225, 700);
            subpath.LineTo(330, 800);
            path.AddSubPath(subpath);
            path.AddRectangle(100, 500, 250, 200);
            path.AddRectangle(120, 520, 210, 160);
            path.Stroke();

            page.Content.Add(path);

            Template.FilledSquare.Matrix = TMatrix.Scale(0.05, 0.01);
            Template.FilledTriangle.Matrix = TMatrix.Scale(0.02, 0.02);
            string square = pdfdoc.AddXObject(Template.FilledSquare);
            string triangle = pdfdoc.AddXObject(Template.FilledTriangle);
            page.Content.GraphicsState.Push();
            page.Content.GraphicsState.CTM = TMatrix.Translation(200, 550);
            page.Content.PaintXObject(square);
            page.Content.GraphicsState.CTM = TMatrix.Translation(-30, 50);
            page.Content.PaintXObject(triangle);
            page.Content.GraphicsState.CTM = TMatrix.Translation(90, 0);
            page.Content.PaintXObject(triangle);
            page.Content.GraphicsState.Pop();
        }

        private void buttonRemovePage_Click(object sender, EventArgs e)
        {
            pdfdoc.PageTree.Kids.Items.Remove(page);
            pdfdoc.PdfObjects.Remove(page.Identifier);
            pdfdoc.PdfObjects.Remove(page.Content.Identifier);

            ShowPageNumber();
        }

        private void buttonRotatePage_Click(object sender, EventArgs e)
        {
            page.Rotate += 90;
        }
    }
}

Template.FilledSquareTemplate.FilledTriangle被定义为FormXOjbects

public class Template
{
  static FormXObject square;
  public static FormXObject FilledSquare
  {
    get
    {
        if (square == null)
        {
            square = new FormXObject();
            square.BoundingBox = new PdfRectangle(0, 0, 1000, 1000);
            Path path = new Path();
            path.AddRectangle(0,0,1000,1000);
            path.Fill();


            square.Content.Add(path);
        }
        return square;
    }
  }

  static FormXObject triangle;
  public static FormXObject FilledTriangle
  {
    get
    {
        if (triangle == null)
        {
            triangle = new FormXObject();
            triangle.BoundingBox = 
                 new PdfRectangle(0, 0, 1000, 1000);



            SubPath subpath = new SubPath(0, 0);
            subpath.LineTo(500, 1000);
            subpath.LineTo(1000, 0);
            subpath.Close();
            Path path = new Path();
            path.Add(subpath);
            path.Fill();
            triangle.Content.Add(path);
        }
        return triangle;
    }
  }

示例输出

待办事项

  • 颜色空间和颜色值
  • 插入图像
  • TrueType字体
  • 注解
  • 流过滤器
  • ...
© . All rights reserved.