2005年08月28日

因为空间的问题,我上传到http://hardrock.cnblogs.com上了

下载路径为http://hardrock.cnblogs.com/Files/hardrock/iTextSharp.tutorial.zip

介绍参考http://hardrock.cnblogs.com/archive/2005/08/28/224200.html

因为工作的关系,iTextSharp tutorial的翻译工作只好暂时搁浅。

2005年08月19日

经过近一个星期(利用早晨的时间)调试了http://itextsharp.sourceforge.net/tutorial/下所有教程,总计111个程序(多数还没有来得及研究,只是调试通过,正确输出结果),除了Chap0908(没有PdfBarcode类,无法测试),并另外又补充了10个没有被收录的程序(来自iText的教程,补充工作继续中)。

测试的同时发现了iTextSharp的2个bug,其中一个在最新版本已经修改过来了,还有一个是我今天刚提交的。

另外添加了对STSong-Light这类字体的支持,这样对PDF的Form填写也可以方便实现了。

http://switch.dl.sourceforge.net/sourceforge/itextsharp/itextsharp-3.0.6.zip

http://switch.dl.sourceforge.net/sourceforge/itextsharp/itextsharp-3.0.6-dll.zip

Changes in iTextSharp 3.0.6 (2005-08-18) 
 
- constructor Image(Image) didn’t copy one of the fields 
 
- Image.ScaledToFit() didn’t take rotation into account 
 
- Table.Width was not being overriden. The result was an exception in PdfDocument 
 
- added BaseFont.CorrectArabicAdvance() to make Arabic Diactrics (tashkeel) 
have zero advance. Some Microsoft fonts like Arial.ttf have non-zero advances 
that confuse the Arabic shaper. 
 
- in PdfDocument the waiting image in the last page was not being placed 
 
- PdfString didn’t output the BOM in Unicode 
 
- PdfStamper supports encryption in append mode 
 
- added verbose analysis of the permissions in PdfEncryptor 
 
- fixed a conversion bug in PdfPCell.NoWrap 
 
- PdfReader.SelectPages() is working again 
 
- PdfWriter.PrintScalingNone had the wrong value 
 
- fixed a conversion bug in SimpleBookmark.IterateOutlines() 
 
- MultiColumnText didn’t respect mirrored margins 
 
- in RTF added the option for chars above ‘z’ to not be encoded in Unicode 
to support older Word versions 

测试例子(翻译自Chap13_form.java程序,已经成功转为Chap13_form.cs,iTextSharp中没有收录这个iText下的教程代码):
            String[,] colorvalues = {{"#FF0000", "Red"}, {"#00FF00", "Green"}, {"#0000FF", "Blue"}};

            acroForm.AddSelectList("list2", colorvalues, "#0000FF", helv, fontSize, 315, 550, 450, 600);
            acroForm.AddComboBox("combo2", colorvalues, "#0000FE", false, helv, fontSize, 315, 440, 450, 490);

出错:System.IndexOutOfRangeException

AddComboBox的bug比较隐蔽,除非你故意把defaultValue输为colorvalues 数组中不存在的值,否则不会导致错误抛出。

public PdfFormField AddComboBox(string name, string[,] options, string defaultValue, bool editable, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
        PdfFormField choice = PdfFormField.CreateCombo(writer, editable, options, 0);
        SetChoiceParams(choice, name, defaultValue, llx, lly, urx, ury);
        string value = null;
        for (int i = 0; i < options.GetLength(0); i++) {//Steven Lee 20050819,原来为options.Length
            if (options[i, 0].Equals(defaultValue)) {
                value = options[i, 1];
                break;
            }
        }
        if (value == null) {
            value = options[0, 1];
        }
        DrawSingleLineOfText(choice, value, font, fontSize, llx, lly, urx, ury);
        AddFormField(choice);
        return choice;
    }

public PdfFormField AddSelectList(string name, string[,] options, string defaultValue, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
        PdfFormField choice = PdfFormField.CreateList(writer, options, 0);
        SetChoiceParams(choice, name, defaultValue, llx, lly, urx, ury);
        StringBuilder text = new StringBuilder();
        for (int i = 0; i < options.GetLength(0); i++) {//Steven Lee 20050819,原来为options.Length
            text.Append(options[i, 1]).Append("\n");
        }
        DrawMultiLineOfText(choice, text.ToString(), font, fontSize, llx, lly, urx, ury);
        AddFormField(choice);
        return choice;
    }

2005年08月14日

        今天调试了http://itextsharp.sourceforge.net上第一章的教程,竟然发现多数都无法调试通过(估计是使用转换工具转换过来的),而且主要是方法首字母应该转为大写的问题,当然还有一部份是其他原因,感觉真的不是很爽,花了1个小时的时间把第一章的全部教程都修改了下,现在可以了,方便的时候会传到网上供大家分享。

2005年08月12日

http://gmail.512j.com/soft/Total.Training.For.(Adobe.Acrobat.7.Professional).(Rls.Date-05-18-05).{4CD’s}.A[m]D.torrent

应一些朋友的要求,重新找到这个torrent,感兴趣的话就快些下载吧。

2005年08月11日

今天在调试书签导入的时候发现SimpleBookmark.cs的一处bug(注意对比我红色字体标记部分):

源程序是:

 internal static Object[] IterateOutlines(PdfWriter writer, PdfIndirectReference parent, ArrayList kids, bool namedAsNames) {
            PdfIndirectReference[] refs = new PdfIndirectReference[kids.Count];
            for (int k = 0; k < refs.Length; ++k)
                refs[k] = writer.PdfIndirectReference;
            int ptr = 0;
            int count = 0;
            foreach (Hashtable map in kids) {
                ++ptr;
                Object[] lower = null;
                ArrayList subKid = (ArrayList)map["Kids"];
                if (subKid != null && subKid.Count > 0)
                    lower = IterateOutlines(writer, refs[ptr], subKid, namedAsNames);
                PdfDictionary outline = new PdfDictionary();
                ++count;
                if (lower != null) {
                    outline.Put(PdfName.FIRST, (PdfIndirectReference)lower[0]);
                    outline.Put(PdfName.LAST, (PdfIndirectReference)lower[1]);
                    int n = (int)lower[2];
                    if ("false".Equals(map["Open"])) {
                        outline.Put(PdfName.COUNT, new PdfNumber(-n));
                    }
                    else {
                        outline.Put(PdfName.COUNT, new PdfNumber(n));
                        count += n;
                    }
                }
                outline.Put(PdfName.PARENT, parent);
                if (ptr > 0)
                    outline.Put(PdfName.PREV, refs[ptr - 1]);
                if (ptr < refs.Length – 1)
                    outline.Put(PdfName.NEXT, refs[ptr + 1]);
                outline.Put(PdfName.TITLE, new PdfString((String)map["Title"], PdfObject.TEXT_UNICODE));
                String color = (String)map["Color"];
                if (color != null) {
                    try {
                        PdfArray arr = new PdfArray();
                        StringTokenizer tk = new StringTokenizer(color);
                        for (int k = 0; k < 3; ++k) {
                            float f = float.Parse(tk.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
                            if (f < 0) f = 0;
                            if (f > 1) f = 1;
                            arr.Add(new PdfNumber(f));
                        }
                        outline.Put(PdfName.C, arr);
                    } catch {} //in case it’s malformed
                }
                String style = (String)map["Style"];
                if (style != null) {
                    style = style.ToLower();
                    int bits = 0;
                    if (style.IndexOf("italic") >= 0)
                        bits |= 1;
                    if (style.IndexOf("bold") >= 0)
                        bits |= 2;
                    if (bits != 0)
                        outline.Put(PdfName.F, new PdfNumber(bits));
                }
                CreateOutlineAction(outline, map, writer, namedAsNames);
                writer.AddToBody(outline, refs[ptr]);//这里变成了从refs[1]到refs[refs.Lenght]了,结果自然而知了。
            }
            return new Object[]{refs[0], refs[refs.Length - 1], count};
        }

修改后的程序为:

 internal static Object[] IterateOutlines(PdfWriter writer, PdfIndirectReference parent, ArrayList kids, bool namedAsNames) {
            PdfIndirectReference[] refs = new PdfIndirectReference[kids.Count];
            for (int k = 0; k < refs.Length; ++k)
                refs[k] = writer.PdfIndirectReference;
            int ptr = 0;
            int count = 0;
            foreach (Hashtable map in kids) {                
                Object[] lower = null;
                ArrayList subKid = (ArrayList)map["Kids"];
                if (subKid != null && subKid.Count > 0)
                    lower = IterateOutlines(writer, refs[ptr], subKid, namedAsNames);
                PdfDictionary outline = new PdfDictionary();
                ++count;
                if (lower != null) {
                    outline.Put(PdfName.FIRST, (PdfIndirectReference)lower[0]);
                    outline.Put(PdfName.LAST, (PdfIndirectReference)lower[1]);
                    int n = (int)lower[2];
                    if ("false".Equals(map["Open"])) {
                        outline.Put(PdfName.COUNT, new PdfNumber(-n));
                    }
                    else {
                        outline.Put(PdfName.COUNT, new PdfNumber(n));
                        count += n;
                    }
                }
                outline.Put(PdfName.PARENT, parent);
                if (ptr > 0)
                    outline.Put(PdfName.PREV, refs[ptr - 1]);
                if (ptr < refs.Length – 1)
                    outline.Put(PdfName.NEXT, refs[ptr + 1]);
                outline.Put(PdfName.TITLE, new PdfString((String)map["Title"], PdfObject.TEXT_UNICODE));
                String color = (String)map["Color"];
                if (color != null) {
                    try {
                        PdfArray arr = new PdfArray();
                        StringTokenizer tk = new StringTokenizer(color);
                        for (int k = 0; k < 3; ++k) {
                            float f = float.Parse(tk.NextToken(), System.Globalization.NumberFormatInfo.InvariantInfo);
                            if (f < 0) f = 0;
                            if (f > 1) f = 1;
                            arr.Add(new PdfNumber(f));
                        }
                        outline.Put(PdfName.C, arr);
                    } catch {} //in case it’s malformed
                }
                String style = (String)map["Style"];
                if (style != null) {
                    style = style.ToLower();
                    int bits = 0;
                    if (style.IndexOf("italic") >= 0)
                        bits |= 1;
                    if (style.IndexOf("bold") >= 0)
                        bits |= 2;
                    if (bits != 0)
                        outline.Put(PdfName.F, new PdfNumber(bits));
                }
                CreateOutlineAction(outline, map, writer, namedAsNames);
                writer.AddToBody(outline, refs[ptr]);
                ++ptr;
            }
            return new Object[]{refs[0], refs[refs.Length - 1], count};
        }

主题是PDF的应用与开发以及纺织服装行业信息化。

http://gmail.512j.com/forum

欢迎光临

2005年08月10日

http://soft.rubypdf.com/softwares/pdf-bookmark-extractor

About PDF Bookmark Extractor 1.0

从PDF中提取书签,然后存为xml或者txt,也可以在textBox中显示,需要Microsoft .Net Framework 1.1

Allows extract bookmarks(outlines) from a given PDF
and show it in textBox, save it as XML or txt format.
Supports unicode bookmarks.
Is Free software,any question and suggestion please contract:
steedsoft@gmail.com
http://www.steedsoft.com
http://blog.donews.com/rocsky
Thanks for iTextSharp

notice:
this software need Microsoft .Net Framework 1.1 support,you can get it from
http://download.microsoft.com/download/7/b/9/7b90644d-1af0-42b9-b76d-a2770319a568/dotnetfx.exe

2005年08月08日

 

利用dataset relationshipsscript设计有subreport的报表

  1. 在工程中添加两个报表文件

Add New item方式,一个命名为rptMain,为主报表,一个命名为rptSub,subreport,想获得的效果如下。



  1. 设计报表

  1. 添加 GroupHeader/Footer sectionrptMain.

  2. group header做如下修改:

    1. 名字改为 ghCompanies

    2. DataField 改为 CompanyName

    3. GroupKeepTogether property All

  1. 再次添加 GroupHeader/Footer section rptMain.

  2. group header做如下修改:

  1. 名字改为ghOrders

  2. Change the DataField to OrderDate

  3. Change the GroupKeepTogether property to All

  1. 添加下面的控件到rptMain,并按指示命名控件:

    Control

    DataField

    Name

    Text/Caption

    Section

    Location

    TextBox

    CompanyName

    txtCompanyName

    Company Name

    ghCompanies

    0, 0

    TextBox

    OrderDate

    txtOrderDate

    Order Date

    ghOrders

    1, 0

    TextBox

    RequiredDate

    txtRequiredDate

    Required Date

    ghOrders

    3.5, 0

    TextBox

    ShippedDate

    txtShippedDate

    Shipped Date

    ghOrders

    5.5, 0

    Label

    (Empty string)

    lblOrderDate

    Ordered:

    ghOrders

    0, 0

    Label

    (Empty string)

    lblRequiredDate

    Required:

    ghOrders

    2.5, 0

    Label

    (Empty string)

    lblShippedDate

    Shipped:

    ghOrders

    4.875, 0

    Subreport

    (Empty string)

    Subreport1

    (Empty string)

    Detail

    0, 0

  2. 添加 GroupHeader/Footer sectionrptSub.

  3. group header做如下修改:

  1. 名字改为 ghOrderDetails

  2. DataField 改为 [order details].orderID

  1. GroupHeader section部分添加如下控件:

    Control

    Name

    Text/Caption

    Location

    Label

    lblUnitPrice

    Unit Price

    4.375, 0

    Label

    lblDiscount

    Discount

    5.5, 0

    Label

    lblProductName

    Product Name

    0.0625, 0

    Label

    lblQuantity

    Quantity

    3.25, 0

    Line

    Line1

    (Empty string)

    X1 = 3.1875

    Y1 = 0

    X2 = 3.1875

    Y2 = 0.1875

    Line

    Line2

    (Empty string)

    X1 = 4.3125

    Y1 = 0

    X2 = 4.3125

    Y2 = 0.1875

    Line

    Line3

    (Empty string)

    X1 = 5.4375

    Y1 = 0

    X2 = 5.4375

    Y2 = 0.1875

    Line

    Line4

    (Empty string)

    X1 = 0

    Y1 = 0.1875

    X2 = 6.5

    Y2 = 0.1875

  2. Detail section部分添加如下控件:

Control

DataField

Name

Text/Caption

Misc Details

Location

TextBox

ProductName

txtProductName

Product Name

(Empty string)

0.0625, 0

TextBox

Quantity

txtQuantity

Quantity

(Empty string)

3.25, 0

TextBox

order details.UnitPrice

txtUnitPrice

Unit Price

OutputFormat = Currency

4.375, 0

TextBox

Discount

txtDiscount

Discount

OutputFormat = Currency

5.5, 0

Line

(Empty string)

Line5

(Empty string)

(Empty string)

X1 = 3.1875

Y1 = 0

X2 = 3.1875

Y2 = 0.1875

Line

(Empty string)

Line6

(Empty string)

(Empty string)

X1 = 4.3125

Y1 = 0

X2 = 4.3125

Y2 = 0.1875

Line

(Empty string)

Line7

(Empty string)

(Empty string)

X1 = 5.4375

Y1 = 0

X2 = 5.4375

Y2 = 0.1875

Line

(Empty string)

Line8

(Empty string)

(Empty string)

X1 = 0

Y1 = 0.1875

X2 = 6.5

Y2 = 0.1875

  1. rptMain报表中添加脚本

  1. 点击report toolbar上的修改脚本图标。

  1. 添加如下代码

[C#]
int cnt;

public void Detail_Format()

{

System.Data.DataRow dr = null;

if(((System.Data.DataSet)rpt.DataSource).Tables["orders"].Rows.Count>cnt)

{

dr = ((System.Data.DataSet)rpt.DataSource).Tables["orders"].Rows[cnt];

cnt++;

}

DataDynamics.ActiveReports.ActiveReport rptSub = new DataDynamics.ActiveReports.ActiveReport();

rptSub.LoadLayout(rptPath);

((DataDynamics.ActiveReports.SubReport)rpt.Sections["Detail"].Controls["SubReport1"]).Report= rptSub;

((DataDynamics.ActiveReports.SubReport)rpt.Sections["Detail"].Controls["SubReport1"]).Report.DataSource = dr.GetChildRows(((System.Data.DataSet)rpt.DataSource).Relations["Order_Details"]);

3.点 OK 继续.

4.在rptSub报表中添加脚本

[C#]

int cnt;

public void Detail_Format()

{

cnt++;

if(cnt % 2 == 0)

{

rpt.Sections["Detail"].BackColor = System.Drawing.Color.White;

}

else

{

rpt.Sections["Detail"].BackColor = System.Drawing.Color.BlanchedAlmond;

}

}

5.进行主程序设计

    1. 获得dataset,参考getDataSet方法

    2. 组建脚本,给rptMain传递subreport路径,详见buildScript函数,注意路径必须使用正斜线(/),而不是反斜线(\),否则脚本报错。(实际设计报表时,subreport可能不止一个,可以根据需要来调用buildScript,增加参数传递)

    3. 加载主报表,指定路径,datasetdataMember(即表名),调用预览窗体预览报表。

6.一些注意事项

  1. 如果subreport中有参数(参数的设置方法为“<%para%>”),需要把subreportShowParameterUI property改为false(如果你的确希望它弹出窗口,可以保留设置不变)

  2. 建立dataset时不要忽略了dataRelation,因为在主表的脚本中需要根据该relationships来格式化subreport的输出。

  3. 因为报表脚本中不能使用using,所以如果要使用到特定的类,需要把完整的namespace也写上,可以在IDE中书写脚本,然后拷贝到脚本编辑器里。