CAD密码破解工具(CAD Password) V2015.02.06绿色特别版

下载:CADPassword_19163
CAD密码破解工具

CAD密码破解工具(CAD Password)是一款功能强大的CAD密码恢复工具。它能够对加密的cad图纸进行去除密码操作,软件能够支持cad系列全部版本,包括cad2013,2014最新版。只是暂时还不支持2015版

CAD Password软件特点

1、支持多种组合和密码字典。

2、能够修改字典攻击。

3、支持新的AutoCAD 2013文件格式。

4、支持多达32个同步处理线程(多CPU,多核心和HT)。

5、支持Unicode的密码。

发表在 CAD实用软件 | 留下评论

AutoCAD 多标签管理插件 DuoTab 3.600(2006~2015全支持)

插件下载:AutoCAD_Duotab_3.600(2006-2015)
插件名称:AutoCAD DuoTab
当前版本:3.6.0.0
功能:多标签管理插件
开发者:小胖工作室 LiteStudio
授权方式:完全免费,无广告
更新日期:2015.3.7

AutoCAD中界面最精美的多标签插件,与CAD完美融合,功能强大,拥有界面自定义功能。

支持版本AutoCAD2006-2015 32位和64位

3.600增加多文件批量打印功能,速度超快的批量打印,支持范围框选,指定图框块,智能自动识别图框。
支持外部插件,更灵活的功能扩展。
多图打印
coplot.jpg

2015-3-8 12:11 上传

下载附件 (89.89 KB)

 

插件商店
plugin.jpg

2015-3-8 12:11 上传

下载附件 (59.04 KB)

 

3.000标签滚动显示,再多文件也不怕

2.600带来悬浮菜单功能,最大化自定义设置,为不同的图元提供不同的快捷菜单
悬浮菜单.jpg

2014-4-18 11:00 上传

下载附件 (45.47 KB)

 

2.300版本 标签位置可以设置于工具栏下面了如果效果
DuoTab2.png

2013-11-25 15:32 上传

下载附件 (197.36 KB)

 

预览.jpg

2013-2-26 14:56 上传

下载附件 (186.03 KB)

 

有同学希望支持2014,2015。
经测试 for 2013版的完全可以支持 AutoCAD2014。
AutoCAD2015不完全支持,在关闭自带标签,设置经典标签位置选项的情况下可以满足正常使用。

需要注意的是,2014,2015版需要将插件所在位置添加为信任位置,并关闭自带的多标签

本插件经过XP+CAD2006,XP+CAD2007,XP+CAD2009,XP+CAD2010,Win7+2009,Win7+2012,Win7 64位+2010 32位,Win7 64位+2012 64位测试,2013版在Win7+2013,win7 64位+2013 64位,win7 64位+2014 64位,win7 64位+2015 64位中测试,在其他版本中有任何问题,希望大家在回复中具体指出

如果对你有用,别吝啬你的回复啊。

全面支持2006-2015 32位+64位!

安装使用cad中使用Netload命令加载,插件将自动安装,升级直接覆盖原文件即可
更新日志:
2014/9/5 Version 3.000
        1.现在当文件标签过多无法显示时可以用右键或中键拖动标签滚动显示。Ctrl + ← 滚动到开始,Ctrl + → 滚动到最后,Ctrl + ↓ 滚动到活动文件。
        2.现在文件标签可以设置备注名
        3.新增文件归类功能
        4.改变了界面风格(内置原版本主题供切换)
        5.修复了当鼠标移至 相关文件 按钮时,鼠标下移引起的菜单展开不完全的问题
        6.现在收藏夹不再有20个数量的限制,并且多选文件可收藏为文件组
        7.修复了当可移动磁盘不可用时,发送到菜单弹出设备未就绪的问题
        8.现在可以直接拖动标签到收藏夹图标添加收藏
        9.增加拖动标签排序的提示功能
        10.当使用快捷键功能时,将处理Ctrl + tab 组合键,修正因标签排序造成的切换问题,按顺序切换

2014/5/31 Version 2.620
        1.增加了lisp批处理功能
        2.修复了卸载不能保存配置的bug

2014/5/5 Version 2.610
        1.现在右击新建按钮将显示自定义模板列表,模板应位于插件目录下的AutoCAD DuoTab Template目录内,若要使用系统模板,请使用系统new命令

2014/4/20 Version 2.600
        1.增加了浮动菜单功能
        2.更新采用自动后台检查,但不会强制更新

2013/11/24 Version 2.300
        1.现在标签可以显示在工具栏下面(绘图区域上面)了
        2.整合了End-All剪贴板
        3.Bug修复

2013/11/8 Version 2.010
        1.增加及时脚本功能
        2.标签右侧增加快速新建文件按钮
        3.增加锁定选项,标签不显示关闭按钮
        4.在标签空白处长按左键,显示最近关闭的文件
        5.更新主题组件,使用*.dtheme主题文件
        6.bug修复

2013/6/28 Version 1.971
       1.增加发送文件到可移动磁盘的功能
       2.增加AutoSweeper功能
       3.界面微调

2013/4/24 Version 1.950
       1.按下Alt键时提示文件编号
       2.修复无法卸载的bug
       3.点击右下角状态栏DuoTab进行配置管理

2013/3/31 Version 1.931
       1.增加快捷键 Shift + Tab 切换布局
       2.增加保存并关闭所有文件选项
       3.快捷键优化,解决了快捷键冲突
       4.现在直接拖动标签即可排序
       5.增加配置加载管理,按需加载该插件
       6.增加单文件不显示标签选项
       7.修复了切换主题时的一个逻辑错误

发表在 CAD实用软件 | 留下评论

最新免费的批量打印程序 v3.5.5版(秋枫)

 
今天为大家带来的是秋枫大哥的最新批量打印软件,软件免费放心使用!希望大家喜欢!群里的朋友们如果觉得用着不错的可以捐助作者开发更好的软件,经济困难点的也可以为该软件提出些更好的改进性意见也算对作者的关心和鼓励。谢谢!
 
捐赠 AutoCAD BatchPlot 批量打印程序

这是一个为AutoCAD2000以上版本设计的单DWG多图纸的批量打印、批量生成布局、批量分图程序。程序根据自己判定的图框位置与尺寸,根据当前的打印机设置,自动调整打印的方式,实现批量打印、批量生成布局、批量分图。

AutoCAD Batchplot 批量打印程序 是一款免费软件。没有任何功能限制。然而,如果你喜欢它想让它继续的发展下去,不断的更新。您可以通过捐赠来支持软件的今后发展。

我的捐赠费用最低为 20 元,然而,如果愿意给我更多的支持,您可以捐助更多。

目前我只支持使用支付宝帐号捐赠。捐赠可登录支付宝网站,直接向支付宝帐号 arcqiufeng@163.com 付款。

支付宝的地址:https://www.alipay.com/

感谢您对我的支持!如果您对我作了捐赠,请同时用电子邮件通知我。我会在将来的版本的说明文档中添加捐赠人姓名。

感谢以下捐赠者:

vermin1986
usestone
李大坤
黄慧明
批量打印程序 v3.5.5

邱枫,2010-07-21
arcqiufeng@gmail.com

  
更新历史:

  • 增加了对部分种类的pc3和打印机程序的PLT文件默认扩展名的的判断。比如PublishToWeb JPG.pc3设备自动设置扩展名为JPG等等 2010-07-21 3.5.5
  • 对话框中“生成PLT文件”改为“打印到文件”。2010-07-21 3.5.5
  • 解决错误: 已加载该 LISP 应用程序 BatchPlot 2010-06-29 3.5.4
  • 允许用户在Batchplot.ini文件中对“自动比例”是否取整,取整时保留的有效位数进行设定。2010-06-28 3.5.3
  • 修复卸载程序的一个List Out of Index错误。 2010-02-24 3.5.2
  • 紧急修复:加载程序出错导致Support路径全部丢失。 2010-02-24 3.5.2
  • 解决安装时中文支持路径问题。LoadBatchplot.lsp 2010-02-23 3.5.1
  • 允许图框选择多个图块名或多个图层名。允许用户自定义默认图块名,图层名。2010-01-31 3.5.0
  • 绕开在某些打印机驱动程序下plt文件名中有英文逗号不能处理的问题(自动替换成全角逗号)。2009-11-29 3.4.0
  • 在Batchplot.ini中添加默认路径和打印截记默认是否打开的支持 2009-11-03 3.3.9
  • 修正绿色形式加载时的一个错误 2009-06-11 3.3.8
  • 提供Batchplot.ini文件供用户自定义少量默认值 2009-05-11 3.3.7
  • 将默认比例改为适合纸张。2009-05-11 3.3.7
  • 将默认打印顺序改为“左右,上下”。2009-05-11 3.3.7
  • 因为AutoLISP中ssnamex的一些奇怪的返回值,所以对图块图框范围的判断方式作了一点修正。2009-01-01 3.3.6
  • 修改对话框文字中的“理正图框”为常用。因天正图框也支持。3.3.5
  • 根据Levis建议修正:文件或布局重名时的选项修改时,对文件名称样板作处理以保持一致。3.3.5
  • 修正:对于非零宽度的普通图层PLINE图框处理。2008年4月7日 3.3.4
  • 对于无法解析正则表达式的系统提供了一种默认文件名的处理方式,保证可以最低限度地正常使用。2008年1月31日 3.3.3
  • 修正:解决某些类型的特殊图框的边界判断处理问题。2008年1月30日 3.3.2
  • 修正:在图名中读取指定图块属性时因程序内部框选范围问题有可能选择到相邻紧贴的图框。2007年12月4日 3.3.1
  • 对于完全重合的图框,允许有1/500的图框宽度的误差。误差在这个范围内的图框认为完全重合。2007年12月2日 3.3.0
  • 允许用户指定PLOT文件的扩展名,解决生成图片、PDF时扩展名不正确的问题。2007年12月1日 3.3.0
  • 修正了文件名自动编号的部分问题。2007年12月1日 3.3.0
  • 解决分图后不保留Group之类的扩展数据问题。现提供两种分式分图。2007年12月1日 3.3.0
  • 解决程序与图像打印机不兼容的问题,现在可以利用它打印成PNG之类的图片了。2007年11月26日 3.2.3
  • 文件布局名称中新增一种仅在需要时才添加的自动编号顺延变量标记<ANum:分隔符:数字位数> 2007年11月25日 3.2.2
  • 对菜单结构调整,增加直接指向批量切图、批量布局之类命令的菜单条并添加相应的命令。2007年11月25日 3.2.2
  • 制作在线捐赠页面。从本版开始,本程序的开发接受用户自愿捐助。2007年11月17日 3.2.1
  • 在AutoCAD界面中添加菜单项,方便调用。2007年11月17日 3.2.1
  • 对最终生成的文件名的中字符合法型作分析,将不合适字符替换成允许的字符。2007年11月17日 3.2.1
  • 对自动命名的逻辑架构作了全新架构, 支持更多的用户自定义功能 2007年11月16日 3.2.0
  • 修正了一个重名处理的 Bug 2007年11月2日 3.1.1
  • 添加切分图纸为一张图一个dwg文件的功能 2007年10月30日 3.1.0
  • 统一了PLT文件、布局、dwg文件的命名模块,添加使用特定图层的文字作为命名的方式 2007年10月30日 3.1.0Beta
  • 修正了新的外框计算方法的一个坐标系转换错误 2007年8月14日 3.0.7
  • 改进了对图块形式的图框的外框计算方法 2007年8月13日 3.0.6
  • 自动去除重复的完全重合的图框 2007年7月13日 3.0.5
  • 自动去除完全相互嵌套的图框(大框套小框)的情况 2007年7月13日 3.0.5
  • 根据实际使用状况,使用特定图形的矩形PLINE作为图框时不再强行要求PLINE线全局宽度为0 2007年7月13日 3.0.5
  • 去除只在模型空间中批量打印的限制 2007年7月13日 3.0.5
  • 添加打印戳记选项与设置按钮 2006年6月1日 3.0.4
  • 保存设置(按应用或确定)时不保存打印份数的值以免误操作 2006年6月1日
  • 修正预览时按N时非正常退出的Bug 3.0.3
  • 修正一个选择PLINE图框的Bug(2006年2月10日)3.0.2
  • 添加“逐份打印”功能。(注意:逐份打印将耗用更多的计算机处理时间,2006年2月1日)
  • 添加“应用”按钮。用于在不打印的情况下保存批量打印的设置(2006年2月1日)
  • 添加命令DeleteBPlotData,用于清除保存在DWG图中的上次批量打印的数据(2006年2月1日)
  • 在理正图框模式下添加支持的图层名”*-图框标题”, “*-图框”(2006年2月1日)3.0.1
  • 修正调试程序时的一个疏忽,把有用的代码注释掉了导致不能选取图块(7月22日)2.9.1
  • 支持除理正图框层外的其它图层上的图框(封闭矩形PLINE)6月29日
  • 支持反向打印(图纸旋转180度)6月29日
  • 理正图框支持“*_TITLE”6月29日
  • 添加支持“理正电气(ELE_TITLE)”图层的图框。(4月8日)
  • 修正“在布局空间中强制使用模型空间线型比例”选项不起作用的问题(程序中笔误)(4月8日)
  • 因DCS与UCS不一致而产生的Bug,Target系统变量(2005.2.24)
  • 在状态栏显示比例与进度信息(7月5日)
  • BUGFIX: 图块列表(7月5日)
  • 提供打印多个Layout的功能(7月1日)
  • 打印不出图框边线问题(6月30日)
  • 在DWG文件中保存上次的批量打印设置(6月28日)
  • 增加打印顺序调整功能(6月25日)
  • 自动打印比例算法调整(6月25日)
  • 支持在UCS下的图块图框(6月25日)
  • 自动旋转设为可选。如选成不自动,可以在页面设置中调整方向(6月25日)
  • 支持在UCS下的理正图框(6月24日)
  • 2.2版。增加图纸偏移与居中选项(6月9日)
  • 增加了一个打印份数的选项。
  • 加入打印机驱动或打印机不存在时的出错处理。
  • 第二版全面改写,新增对话框。
  • 加入对理正图框的支持。
  • 第一版。 秋枫批量打印3.5.5

 

发表在 CAD实用软件 | 留下评论

netload 自动运行

方法一:
1. 在AutoCAD安装目录找到c:\Program Files\AutoCAD 2006\Support\acad2006.lsp
用记事本打开,在最后加入(下段代码第二行即可,注意路径)
(if (not (=  (substr (ver) 1 11) “Visual LISP”)) (load “acad2006doc.lsp”))
(command “netload” “C:\\MXCAD\\bin\\Debug\\MXCAD.dll”)
;; Silent load.
(princ)

2. AutoCAD设置(重要,必须设置):
工具-选项-文件-支持文件搜索路径-添加-浏览到MXCAD路径

方法二:
修改注册表,新建记事本文件,重命名为netload.reg,加入以下内容,然后双击文件将信息添加到注册表即可。
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R16.2\ACAD-4001:804\Applications\MXCAD]
“LOADER”=”C:\\MXCAD\\bin\\Debug\\MXCAD.dll”
“MANAGED”=dword:0001c101
“LOADCTRLS”=dword:0001c102″LOADCTRLS”:控制程序随CAD加载的方式,设为Ox02随CAD启动一起加载;
“LOADER”:告诉CAD所要加载的程序的路径;
“MANAGED”:设为Ox01,告诉CAD这是托管程序。
—————————–
附注:注册表键值”LOADCTRLS”控制说明,控制ARX程序的加载方式(上例中使用的是Ox02随CAD启动一起加载)
0x01:Load the application upon detection of proxy object.
   当代理对像被控知时另载相应ARX程序.

0x02:Load the application upon AutoCAD startup.
   当AutoCAD启动时加载相应ARX程序.

0x04:Load the application upon invocation of a command.
   当输入命令时加载相应ARX程序.

0x08:Load the application upon request by the user or another application.
   当有用户或别的程序请求时加载相应ARX程序.

0x10:Do not load the application.
   从不加载该应用程序.

0x20:Load the application transparently.
   显式加载该应该程序.(不知该项译法是否有误)
—————————–
打包时,将上述注册表项添加到注册表中,即可实现安装时自动配置。
        private bool WriteRegistryKey()
        {
            try
            {
                RegistryKey localMachine = Registry.LocalMachine;
                RegistryKey SOFTWARE = localMachine.OpenSubKey(“SOFTWARE”, true);
                RegistryKey Autodesk = SOFTWARE.OpenSubKey(“Autodesk”, true);
                RegistryKey AutoCAD = Autodesk.OpenSubKey(“AutoCAD”, true);
                RegistryKey R16_2 = AutoCAD.OpenSubKey(“R16.2”, true);
                RegistryKey ACAD = R16_2.OpenSubKey(“ACAD-4001:804”, true);
                RegistryKey Applications = ACAD.OpenSubKey(“Applications”, true);

                RegistryKey MXCAD = Applications.CreateSubKey(“MXCAD”);
                MXCAD.SetValue(“LOADCTRLS”, 0x02);
                MXCAD.SetValue(“LOADER”, this.targetdir + @”bin\Debug\MXCAD.dll”);
                MXCAD.SetValue(“MANAGED”, 0x01);
                return true;
            }
            catch
            {
                return false;
            }
        }

发表在 CAD技巧 | 留下评论

.net使用免费开源类库操作Excel 通吃所有Excel

主要找到以下类库:

MyXls(http://sourceforge.net/projects/myxls/)
Koogra(http://sourceforge.net/projects/koogra/)
ExcelLibrary(http://code.google.com/p/excellibrary/)
ExcelPackage(http://excelpackage.codeplex.com/)
EPPlus(http://epplus.codeplex.com/)
LinqToExcel(http://code.google.com/p/linqtoexcel/)
NetOffice(http://netoffice.codeplex.com/) 需安装Office Excel

从1-6的类库均不需要安装Office,不使用Office COM组件;而NetOffice需要安装Office,它提供的是与Office COM组件差不多的功能。

注:本文仅简单演示读取与创建Excel。

准备测试代码

首先,为这些类库准备一些测试代码,用于之后的测试。

aspx主要代码如下:

程序代码:
<asp:FileUpload ID=FileUpload1 runat=server />
<asp:Button ID=Button1 runat=server Text=上传Excel
    onclick=Button1_Click />
    <asp:Button ID=Button2 runat=server Text=下载Excel
    onclick=Button2_Click />
<asp:GridView ID=GridView2 runat=server>
</asp:GridView>

aspx.cs主要代码如下:

程序代码:
private void RenderToBrowser(MemoryStream ms, string fileName)
{
    if (Request.Browser.Browser == IE)
        fileName = HttpUtility.UrlEncode(fileName);
    Response.AddHeader(Content-Disposition, attachment;fileName= + fileName);
    Response.BinaryWrite(ms.ToArray());
}

protected void Button1_Click(object sender, EventArgs e)
{
    if (FileUpload1.HasFile)
    {//读取上传的文件绑定到GridView
        GridView1.DataSource = ReadByXXX(FileUpload1.FileContent);
        GridView1.DataBind();
    }
}

protected void Button2_Click(object sender, EventArgs e)
{
    DataTable table = new DataTable();
    table.Columns.Add(aa, typeof(string));
    table.Columns.Add(bb, typeof(string));
    table.Columns.Add(cc, typeof(string));
    for (int i = 0; i < 10; i++)
    {
        string a = DateTime.Now.Ticks.ToString();
        Thread.Sleep(1);
        string b = DateTime.Now.Ticks.ToString();
        Thread.Sleep(1);
        string c = DateTime.Now.Ticks.ToString();
        Thread.Sleep(1);
        table.Rows.Add(a, b, c);
    }
    //从DataTable创建Excel并下载
    RenderToBrowser(CreateByXXX(table), test.xls);
}

MyXls

MyXls支持Office Excel 97-2003格式(Biff8格式),但目前并不支持formula即公式;网上流传的支持2007是错误的说法。

使用它还需要注意的是,它与Office PIA一样,索引号是从1开始的。

另外不得不说的是,它的构造函数、Save方法、属性中的FileName让人看的眼花瞭乱,无所适从呐-_-。

主要使用的类型都位于org.in2bits.MyXls空间下,主要测试代码如下:

程序代码:
MemoryStream CreateByMyXls(DataTable table)
{
    XlsDocument doc = new XlsDocument();
    Worksheet sheet = doc.Workbook.Worksheets.Add(Sheet1);
    int colCount = table.Columns.Count;
    for (int i = 1; i <= colCount; i++)
    {
        sheet.Cells.Add(1, i, table.Columns[i – 1].Caption);
    }

    int k = 2;
    foreach (DataRow row in table.Rows)
    {
        for (int i = 1; i <= colCount; i++)
        {
            sheet.Cells.Add(k, i, row[i – 1]);
        }
        k++;
    }
    MemoryStream ms = new MemoryStream();
    doc.Save(ms);
    return ms;
}

DataTable ReadByMyXls(Stream xlsStream)
{
    XlsDocument doc = new XlsDocument(xlsStream);
    DataTable table = new DataTable();
    Worksheet sheet = doc.Workbook.Worksheets[0];
    int colCount = sheet.Rows[1].CellCount;
    int rowCount = sheet.Rows.Count;

    for (ushort j = 1; j <= colCount; j++)
    {
        table.Columns.Add(new DataColumn(sheet.Rows[1].GetCell(j).Value.ToString()));
    }

    for (ushort i = 2; i < rowCount; i++)
    {
        DataRow row = table.NewRow();
        for (ushort j = 1; j <= colCount; j++)
        {
            row[j – 1] = sheet.Rows[i].GetCell(j).Value;
        }
        table.Rows.Add(row);
    }

    return table;
}

Koogra

Koogra支持Office 97-2003(Biff8)以及Office 2007以上(Xlsx)格式,但它仅提供读取功能,没有相关的创建Excel功能;另需要注意它的索引号又是从0开始的。

我在几台机器上测试不太稳定,即有的机器直接不能运行,没有深究什么问题。

操作xls格式的类型主要位于Net.SourceForge.Koogra.Excel空间,主要测试代码如下:

程序代码:
public static DataTable ReadByKoogra(Stream xlsStream)
{
    DataTable table = new DataTable();
    Workbook book = new Workbook(xlsStream);
    Worksheet sheet = book.Sheets[0];

    Row headerRow = sheet.Rows[0];
    uint colCount = headerRow.Cells.MaxCol;
    uint rowCount = sheet.Rows.MaxRow;
    Row tempr = null;
    Cell tempc = null;

    for (ushort j = 0; j <= colCount; j++)
    {
        tempc = headerRow.Cells[j];
        if (tempc != null)
            table.Columns.Add(new DataColumn((tempc.Value ?? string.Empty).ToString()));
    }

    for (ushort i = 0; i <= rowCount; i++)
    {
        DataRow row = table.NewRow();
        tempr = sheet.Rows[i];

        for (ushort j = 0; j <= colCount; j++)
        {
            tempc = tempr.Cells[j];
            if (tempc != null)
                row[j] = tempc.Value;
        }
        table.Rows.Add(row);
    }

    return table;
}

操作XLSX格式的类型主要位于Net.SourceForge.Koogra.Excel2007空间,主要测试代码如下:

程序代码:
public static DataTable ReadByKoogra(Stream xlsStream)
{
    DataTable table = new DataTable();
    Workbook book = new Workbook(xlsStream);
    Worksheet sheet = book.GetWorksheet(0);

    Row headerRow = sheet.GetRow(0);
    uint colCount = sheet.CellMap.LastCol;
    uint rowCount = sheet.CellMap.LastRow;
    Row tempr = null;
    ICell tempc = null;

    for (ushort j = 0; j <= colCount; j++)
    {
        tempc = headerRow.GetCell(j);
        if (tempc != null)
            table.Columns.Add(new DataColumn((tempc.Value ?? string.Empty).ToString()));
    }

    for (ushort i = 0; i <= rowCount; i++)
    {
        DataRow row = table.NewRow();
        tempr = sheet.GetRow(i);

        for (ushort j = 0; j <= colCount; j++)
        {
            tempc = tempr.GetCell(j);
            if (tempc != null)
                row[j] = tempc.Value;
        }
        table.Rows.Add(row);
    }

    return table;
}

ExcelLibrary

听说这是国人开发的,目前支持97-2003(biff8)格式,未来可能会支持xlsx格式。它使用二维数组的方式来操作,这种方式比较接近Office PIA,另外,它的索引号是从0开始的。

在测试时,创建出的Excel有时内容是空的,可能存在bug。

它提供了一个DataSetHelper的工具类,用于从DataTable/DataSet和WorkBook之间的转换,但这个工具类不支持对流的操作,所以还是自己写测试代码(ExcelLibrary空间):

程序代码:
MemoryStream CreateByExcelLibrary(DataTable table)
{
    Workbook book = new Workbook();
    Worksheet sheet = new Worksheet(Sheet123);
   
    int colCount = table.Columns.Count;
    for (int i = 0; i < colCount; i++)
    {
        sheet.Cells[0, i] = new Cell(table.Columns[i].Caption);
    }

    int k = 1;
    foreach (DataRow row in table.Rows)
    {
        for (int i = 0; i < colCount; i++)
        {
            sheet.Cells[k, i] = new Cell(row[i]);
        }
        k++;
    }
    book.Worksheets.Add(sheet);
    MemoryStream ms = new MemoryStream();
    book.Save(ms);
    return ms;
}

DataTable ReadByExcelLibrary(Stream xlsStream)
{
    DataTable table = new DataTable();
    Workbook book = Workbook.Load(xlsStream);
    Worksheet sheet = book.Worksheets[0];

    int colCount = sheet.Cells.LastColIndex;
    int rowCount = sheet.Cells.LastRowIndex;

    for (ushort j = 0; j <= colCount; j++)
    {
        table.Columns.Add(new DataColumn(sheet.Cells[0, j].StringValue));
    }

    for (ushort i = 1; i <= rowCount; i++)
    {
        DataRow row = table.NewRow();
        for (ushort j = 0; j <= colCount; j++)
        {
            row[j] = sheet.Cells[i, j].Value;
        }
        table.Rows.Add(row);
    }

    return table;
}

ExcelPackage与EPPlus

ExcelPackage它主要支持OOXML即Office Open XML标准,Office 2007以上XLSX格式的读写;但它不支持对流的操作,仅支持对实体文件的操作。

EPPlus全称应该是ExcelPackage Plus,即ExcelPackage的增强版,它在ExcelPackage的基础上,增强了许多功能包括对流、Linq的支持,可以说相当不错。

它的索引号是从1开始的,主要使用的类型位于OfficeOpenXml空间,具体测试代码如下:

程序代码:
MemoryStream CreateByExcelLibrary(DataTable table)
{
    using (ExcelPackage package = new ExcelPackage())
    {
        ExcelWorksheet sheet = package.Workbook.Worksheets.Add(sheet111);

        int colCount = table.Columns.Count;
        for (int i = 0; i < colCount; i++)
        {
            sheet.Cells[1, i + 1].Value = table.Columns[i].Caption;
        }

        int k = 2;
        foreach (DataRow row in table.Rows)
        {
            for (int i = 0; i < colCount; i++)
            {
                sheet.Cells[k, i + 1].Value = row[i];
            }
            k++;
        }

        MemoryStream ms = new MemoryStream();
        package.SaveAs(ms);
        return ms;
    }
}

DataTable ReadByExcelLibrary(Stream xlsStream)
{
    DataTable table = new DataTable();
    using (ExcelPackage package = new ExcelPackage(xlsStream))
    {
        ExcelWorksheet sheet = package.Workbook.Worksheets[1];

        int colCount = sheet.Dimension.End.Column;
        int rowCount = sheet.Dimension.End.Row;

        for (ushort j = 1; j <= colCount; j++)
        {
            table.Columns.Add(new DataColumn(sheet.Cells[1, j].Value.ToString()));
        }

        for (ushort i = 2; i <= rowCount; i++)
        {
            DataRow row = table.NewRow();
            for (ushort j = 1; j <= colCount; j++)
            {
                row[j – 1] = sheet.Cells[i, j].Value;
            }
            table.Rows.Add(row);
        }
    }

    return table;
}

LinqToExcel,NetOffice…

至于LinqToExcel,只能说是颗糖而已,不支持对流的操作,实在是无爱啊,不多说。

NetOffice提供与Office PIA相似的功能,又需要安装Office,实在不适合在web场景中使用,所以也不多说。

结尾

对于Excel 97-2003格式,还是用NPOI最好,API设计比较好(上面这些类库又是0又是1的索引号和二维数组实在让人好晕);而对于2007(xlsx)以上版本,可以使用EPPlus;这样基本所有的Excel格式通吃了。

发表在 C# | 留下评论

无法访问服务器上的ini文件,怎么解决

第一步,打开IIS,选择对应的网站,右击属性,弹出的属性框,选择“HTTP头”,如下图(1)所示:

无法访问服务器上的ini文件,怎么解决?图(1)

第二步,点击“MIME类型”,进入“MIME类型”列表,如下图(2)所示,现在里面是空白的。
无法访问服务器上的ini文件,怎么解决? 图(2)

第三步,点击“新建”按钮,弹出“MIME类型”对话框,如下图(3)所示:

无法访问服务器上的ini文件,怎么解决?图(3)

扩展名: .ini ;MIME类型:ini(这样写的话浏览器会直接弹出下载对话框)或者text/plain(这样写浏览器会直接将ini文件内容展示出来,类似于txt的配置)
   第四步,访问这个ini文件,OK了,这个文件可以访问了。搞定了,其实也很简单的,呵呵……估计类似的文件,也是在这里添加。

 

发表在 网站建设 | 留下评论

升级到云主机了

以前的时候网站租用的西部数码的”虚拟主机”

其它的各方面都还挺满意,价钱也蛮实惠的。

但是就是有一点限制挺不好的,就是每月的流量有限制。

没办法很多东西都只能上传到百度云上

下载可能会有点麻烦。

现在好了,升级到了云主机,虽然价钱是贵了一些,但是还是值的。

为大家提供更好的服务,希望大家多多支持。

谢谢。

发表在 网站建设 | 留下评论

XLS文件格式研究

 

版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处、作者信息和本声明
本页地址:http://www.alongly.com/content/xlsresearch.html

第一章、XLS文件和十六进制

 

1.1 XLS文件和BIFF版本对照

通常我们把EXCEL的文件格式叫做BIFF,即 Binary Interchange File Format的缩写,随着EXCEL的不断升级,其文件格式BIFF也在同步的更新与完善,因此对于不同版本的EXCEL有着不同的BIFF版本,下表对EXCEL目前最常用的版本和BIFF的部分版本进行了对照。

EXCEL版本 BIFF版本
EXCEL 8.0(EXCEL 97) BIFF8
EXCEL 9.0(EXCEL 2000) BIFF8
EXCEL 10.0(EXCEL XP) BIFF8x
EXCEL 11.0(EXCEL 2003) BIFF8x

    其中BIFF8x为BIFF8的扩展版本,它在BIFF8的基础上改动了部分属性值。

1.2 结构知识

在介绍XLS的文件结构时,大家需要知道关于XLS二进制文件的一些基本的结构内容知识:

1、  在文件数据的二进制存储中,低位8字节存放在地址的低位,高位8字节存放在地址的高位,因此在用十六进制编辑器来查看XLS文件时,对于一个完整的双字节,它的显示如 09 08,那么他的十六进制值应该为0x0809。

2、  XLS文件中的每条完整的数据是由一个标识、长度和数据内容来体现的,如某条数据显示 09 08 02 00 00 00,那么09 08代表这条完整数据的标识,02 00代表后面内容的长度,而00 00为实际的内容数据。

3、  在数据结构中,1个block的大小为512bytes,而XLS文件是由整数个block来组成的,因此其大小也均为512的倍数。

4、  XLS文件整体被分为多个子流(SubStream),这些SubStream都由若干个整数倍Block来组成的。

1.3 撰写规范

1、对于数据内容描述的表格,均采用如下样式

Offset

Size

Content

其中

Offset(偏移量):该偏移量是指当前数据内容开始与该段数据内容区开始的偏移值。

Size(大小):该段数据内容区的大小

Content(内容):该段数据内容区的部分值或是说明

2、对于一段完整的数据区的描述方式为:

标识头+ 标识名称 + 标识说明+ 数据内容

第二章、XLS文件格式

2.1 XLS文件框架

XLS文件作为一个文件流(FileStream),是由多个子流(SubStream)构成的,以下的表格将XLS文件的各个SubStream按照顺序依次展现出来,其中包括了对XLS的各个SubStream的大小的说明,这样可以方便于大家对XLS文件格式有个总体的认识,同时我们由下面的各个Substream的大小可以看出,XLS文件的大小最少也为13,824 bytes。

SubStream 描述
XLS Header区 占1 block (512 bytes),固定大小。
WorkBook区 最小占8个block(4096 bytes)
Summary Information区 占8个block(4096 bytes),固定大小。
Document Summary Information区 占8个block(4096 bytes),固定大小。
BigBlock pointer区 占1个block(512 bytes),固定大小。
RootEntry区 占1个block(512 byte s),固定大小。

       其中WorkBook为数据变化区,它会随着文件内容的增大而增大,但始终保持Block的整数倍。

2.2 XLS Header

XLS文件的重要部位,如下表所示,其中所列位置和值对于生成XLS文件尤为重要。

Offset

Size

Content

48

4

ROOT_START_BLOCK_POS,指向ROOT所在Block个数

76

4

BIG_BLOCK_DEPOT_BLOCKS_POS,指向BigBlock所在的Block个数

2.3 WorkBook

以下为WorkBook区的重要内容结构:

0x0809  Workbook Header,即BOF,长度范围1~20

Offset

Size

Content

0

2

存放XLS文件的版本类型

BIFF8/ BIFF8X   0x0600

BIFF7           0x0500

2

2

WorkBook Globals,0x0005

0x0031  FONT,长度24bytes。

0x041E  FORMAT

0x00E0  XF Extend FORMAT

0x0293  STYLE

0x0085  BOUNDSHEET,即Sheet指针区,N个Sheet则有N个0x0085,包含每个Sheet的名称、sheet数据内容在xls文件中的偏移量。

Offset

Size

Content

0

4

该Sheet的BOF的绝对位移量,相对于Workbook

0x008C  Country ,语言和地区设置。

0x00FC  SST内容(Sharing String Table 用来存放字符串,目的是为了让各个sheet都能够共享该SST中字符串内容)

Offset

Size

Content

0

4

数据中所有字符串的数量

4

4

将要放在SST中字符串的数量

以下开始针对每个字符串进行循环处理

8

2

该字符串的长度,若为双字节字符也算做一个

10

1

字符串中若包含双字节字符(如中文),则为0x01,若为纯ASCII字符,则为0x00

11

n

存放字符串信息

0x00FF  Extended SST内容

     在读取XLS文件时显得不重要,但当创建XLS文件时却非常重要

Offset

Size

Content

0

2

每一区块字符串的个数,其值>=8

以下开始针对每一区块字符串进行循环处理

2

4

每一区块第一个字符的绝对位置

6

2

每一区块第一个字符的相对位置

8

2

保留

0x0809  Sheet1内容

     0x0809  Header,20 bytes

     0x020B  Index,16+4*N个字节

Offset

Size

Content

0

4

保留

4

4

第一行的序号

8

4

最后一行的序号(OpenOffice上介绍是sheet结尾的第一个未使用行的序号,行数的基数按0开始)

10

4

指向DEFCOLWIDTH(0x0055)相对于Workbook Header的位置

14

4*N

指向DBCELL(0x00D7)相对于Workbook Header的位置,当存在多个DBCELL时,需要设置多个。

N为该sheet的行数/32

 

 

 

 

 

 

0x0055  DEFCOLWIDTH,6 bytes

0x0200  Dimensions,18 byte,存放sheet1的行数和列数。

Offset

Size

Content

0

4

第一行的序号

4

4

最后一行的序号

8

2

第一列的序号

10

2

最后一列的序号

12

2

保留

Row Block

     0x0208  Row,20 bytes,Sheet中有多少行就有对应多少个0x0208开头的行信息,如果sheet中有5行,那么Row Block的大小就是20*5 bytes。

Offset

Size

Content

0

2

行的序号

2

2

列的序号

     Cell Block     设置sheet中每一个单元格的信息,顺序为针对每一行的每一列依次设置,如00, 01, 02 ……10, 11, 12 ……20, 21, 22……

          0x00FD  LABELSST,14bytes,针对字符串值已经在SST中保存,这里只保存其对应的序号。

          0x027E  RK2,14bytes,针对RK值(指编过码的整型或浮点型值)

          0x00BD  MULRK,28 bytes

     0x00D7  DBCELL,随着行数的变化而发生变化。

Offset

Size

Content

0

4

DBCELL的偏移量减去Row Block中第一个Row的偏移量

4

2

Cell Block中首行的第一个Cell的偏移量减去Row Block中第二个Row的偏移量

以下为循环处理部分,1<n<=Max_Row

6

2

Cell Block中第n行的第一个Cell的偏移量减去第n-1行的第一个Cell的偏移量

当XLS中的行数大于32时,系统将循环处理,对于每个32行内容单独生成Row Block、Cell Block和DBCELL。

0x0809   Sheet2内容

0x0809   Sheet3内容 (如果有Sheet2、Sheet3)

0x000A   EOF,Workbook结束标示符

2.4 Summary Information

属性,如作者,工作表类型等Excel中点击文件—〉属性的部分内容存放在此。

2.5 Document Summary Information

文档的属性,具体存放的内容大家可以研究研究。

2.6 BigBlock Pointer

每四个字节存放一个bigBlockChain。

2.7 Root Entry

文件结尾部分,其中对几个substream进行了描述,每个substream的描述占128个字节。

Offset

Size

Content

0

128

存放文件中Root Entry属性 地址和大小

128

128

Workbook属性,地址和大小,占有实际数据的内容

256

128

SummaryInformation属性,地址和大小

384

128

DocumentSummaryInformation的属性,地址和大小

针对每个128字节内容,其偏移量116后的4个字节为每个区块的开始位置,之后的4个字节为每个区块的大小,地址和大小数据会随着内容量的变化而发生变化。

发表在 C# | 留下评论

C#访问私有方法,字段和属性

增加命名空间:

using System.Reflection;

代码:

public static class PrivateExtension
    {
        public static Object GetPrivateField(Object instance, String fieldname)
        {
            BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
            Type type = instance.GetType();
            FieldInfo field = type.GetField(fieldname, flag);
            while (field == null && type.BaseType != null)
            {
                //访问基类,直到找到对应的字段或者属性或者方法
                type = type.BaseType;
                field = type.GetField(fieldname, flag);
            }
            return field.GetValue(instance);
        }

        public static Object GetPrivateProperty(Object instance, String propertyname)
        {
            BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
            Type type = instance.GetType();
            PropertyInfo field = type.GetProperty(propertyname, flag);
            while (field == null && type.BaseType != null)
            {
                //访问基类,直到找到对应的字段或者属性或者方法
                type = type.BaseType;
                field = type.GetProperty(propertyname, flag);
            }
            return field.GetValue(instance, null);
        }

        public static void SetPrivateField(Object instance, String fieldname, Object value)
        {
            BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
            Type type = instance.GetType();
            FieldInfo field = type.GetField(fieldname, flag);
            while (field == null && type.BaseType != null)
            {
                //访问基类,直到找到对应的字段或者属性或者方法
                type = type.BaseType;
                field = type.GetField(fieldname, flag);
            }
            field.SetValue(instance, value);
        }

        public static void SetPrivateProperty(Object instance, String propertyname, Object value)
        {
            BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
            Type type = instance.GetType();
            PropertyInfo field = type.GetProperty(propertyname, flag);
            while (field == null && type.BaseType != null)
            {
                //访问基类,直到找到对应的字段或者属性或者方法
                type = type.BaseType;
                field = type.GetProperty(propertyname, flag);
            }
            field.SetValue(instance, value, null);
        }

        public static Object CallPrivateMethod(Object instance, String name, params Object[] param)
        {
            BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
            Type type = instance.GetType();
            MethodInfo method = type.GetMethod(name, flag);
            while (method == null && type.BaseType != null)
            {
                //访问基类,直到找到对应的字段或者属性或者方法
                type = type.BaseType;
                method = type.GetMethod(name, flag);
            }
            return method.Invoke(instance, param);
        }
        public static Object CallPrivateMethodEx(Object instance, String name, params Object[] param)
        {
            if (param == null || param.Length == 0)
            {
                return CallPrivateMethod(instance, name, param);
            }
            Type[] types = new Type[param.Length];
            for (int i = 0; i < param.Length; i++)
            {
                types[i] = param[i].GetType();
            }
            BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
            Type type = instance.GetType();
            MethodInfo method = type.GetMethod(name, flag,null,types,null);
            while (method == null && type.BaseType != null)
            {
                //访问基类,直到找到对应的字段或者属性或者方法
                type = type.BaseType;
                method = type.GetMethod(name, flag, null, types, null);
            }
            return method.Invoke(instance, param);
        }
    }

发表在 C# | 留下评论

NPOI读取和写入文件

增加命名空间:

using NPOI.HSSF.UserModel;
using System.IO;

实现代码:

//文件名称
            string fileName = “D:\\test.xls”;
            FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite);
            //读取文件
            HSSFWorkbook book = new HSSFWorkbook(fs);
            fs.Close();
            FileStream fs1 = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite);
            //写入文件
            book.Write(fs1);
            fs1.Close();

发表在 C# | 留下评论

NPOI 1.2 教程 – 2.1.5 创建页眉和页脚

转载:http://tonyqus.sinaapp.com/archives/518

很多人并不知道Excel的页眉和页脚功能,因为在界面上是显示不了页眉和页脚的,必须在打印页面中才能看到,这也直接导致了其设置界面也显得更隐秘,你必须进入页面设置 –> 页眉和页脚才能设置。以下是Office 2007中的设置界面。

image

当你按“自定义页眉”或“自定义页脚”时,你会看到以下界面,Excel把页眉、页脚分成了左中右三部分,这一点绝非单纯体现在界面上,在底层的存储中也是如此。如果你设置的是“左”的内容,底层的存储字符串就会在开头加上&L,如果是“右”的内容则会加上&R,所以HeaderRecord中的字符串看上去是这样的:”&C&LFooter A&R”,这个字符串的意思是仅设置了“左”的内容,内容是Footer A。

image

看了这些我想你应该对页眉和页脚有所了解了,回过头来说NPOI,NPOI中主要是靠HSSFSheet.Header和HSSFSheet.Footer来设置的,这两个属性分别是HSSFHeader和HSSFFooter类型的。

 

参考代码如下:

1
2
3
4
5
6
7
8
HSSFSheet s1 = hssfworkbook.CreateSheet(<SPAN style="COLOR: #006080">"Sheet1"</SPAN>);
s1.CreateRow(0).CreateCell(1).SetCellValue(123);
  
<SPAN style="COLOR: #008000">//set header text</SPAN>
s1.Header.Center = <SPAN style="COLOR: #006080">"This is a test sheet"</SPAN>;
<SPAN style="COLOR: #008000">//set footer text</SPAN>
s1.Footer.Left = <SPAN style="COLOR: #006080">"Copyright NPOI Team"</SPAN>;
s1.Footer.Right = <SPAN style="COLOR: #006080">"created by Tony Qu(瞿杰)"</SPAN>;

 

以上代码中我添加了页眉的Center内容,Footer的Left和Right内容,在打印预览中看到的效果大概是这样的:

页眉

image 

页脚

image

至于一些Excel特殊字符,比如说页码可以用&P,当前日期可以用&D,其他的东西你就自己研究吧。

发表在 C# | 留下评论

NPOI 1.2 教程 – 2.1.4 创建批注

转载:http://tonyqus.sinaapp.com/archives/516

很多人不怎么用Excel中的批注,所以我特地截了张图,让大家知道本节我们要创建的到底是什么东西。

image

在过去,我们恐怕没有办法实现这一功能,因为无论是cvs法、html法、oledb法都没有提供这样的接口,当然Office PIA法可以做到,但是性能实在太差,而且稳定性不好,经常莫名其妙crash(这是某某兄弟给我的反馈,我引用了下,呵呵)。在以后的教程中,你将看到更多在过去无法通过传统方法实现的东西,好戏才刚刚开始。

批注主要有三个属性需要设置,一个是批注的位置和大小、一个是批注的文本、还有一个是批注的作者。

 

批注的位置和大小,在Excel中是与单元格密切相关的,NPOI中通过HSSFClientAnchor的实例来表示,它的构造函数比较复杂,有8个参数,它们分别是

参数

说明

dx1 第1个单元格中x轴的偏移量
dy1 第1个单元格中y轴的偏移量
dx2 第2个单元格中x轴的偏移量
dy2 第2个单元格中y轴的偏移量
col1 第1个单元格的列号
row1 第1个单元格的行号
col2 第2个单元格的列号
row2 第2个单元格的行号

 

例如,如果我们打算让注释显示在B3和E5之间,就应该这么写:

HSSFPatriarch patr = sheet.CreateDrawingPatriarch();
HSSFComment comment1 = patr.CreateComment(new HSSFClientAnchor(0, 0, 0, 0, 1, 2 , 4, 4));

下面我们设置这个批注的内容和作者,这个比较简单:

comment1.String = new HSSFRichTextString("Hello World");
comment1.Author = "NPOI Team";

最后一步就是把批注赋给某个单元格:

HSSFCell cell = sheet.CreateRow(1).CreateCell(1);
cell.CellComment = comment1;

对于批注,你有两种选择,一种是隐藏(默认),一种是显示(即表单一打开就显示该批注),可以通过comment1.Visible属性来控制。

image

看了上面这张图大家就应该明白了,这里有2个批注,下面那个是显示的,上面那个是隐藏的。

发表在 C# | 留下评论

NPOI 1.2 教程 – 2.1.3 创建单元格

转载:http://tonyqus.sinaapp.com/archives/507

用过Excel的人都知道,单元格是Excel最有意义的东西,我们做任何操作恐怕都要和单元格打交道。在Excel中我们要添加一个单元格只需要点击任何一个单元格,然后输入内容就是了,但是Excel底层其实没有这么简单,不同的单元格是有不同的类型的,比如说数值单元格是用NumberRecord表示,文本单元格是用LabelSSTRecord表示,空单元格是用BlankRecord表示。这也就意味着,在设置单元格时,你必须告诉NPOI你需要创建哪种类型的单元格。

要创建单元格首先要创建单元格所在的行,比如,下面的代码创建了第0行:

1
2
HSSFSheet sheet1 = hssfworkbook.CreateSheet("Sheet1");
HSSFRow row1=sheet1.CreateRow(0);

行建好了,就可以建单元格了,比如创建A1位置的单元格:

1
row1.CreateCell(0).SetCellValue(1);

这里要说明一下,SetCellValue有好几种重载,你可以设置单元格为bool、double、DateTime、string和HSSFRichTextString类型。其中对于string类型的重载调用的就是HSSFRichTextString类型的重载,所以是一样的,HSSFRichTextString可用于有字体或者Unicode的文本。

如果你觉得每一行要声明一个HSSFRow很麻烦,可以用下面的方式:

1
sheet1.CreateRow(0).CreateCell(0).SetCellValue("This is a Sample");

这么用有个前提,那就是第0行还没创建过,否则得这么用:

1
sheet1.GetRow(0).CreateCell(0).SetCellValue("This is a Sample");

注意:这里的行在Excel里是从1开始的,但是NPOI内部是从0开始的;列在Excel里面是用字母表示的,而NPOI中也是用从0开始的数字表示的,所以要注意转换。

 

如果你要获得某一个已经创建的单元格对象,可以用下面的代码:

1
sheet1.GetRow(row_index).GetCell(column_index);
发表在 C# | 留下评论

NPOI 1.2 教程 – 2.1.2 创建DocumentSummaryInformation和SummaryInformation

前一节中我们讲解了如何创建一个新的Workbook,但在此过程中大家也许会发现一个细节,这些文件没有包括DocummentSummaryInformation和SummaryInformation头。如果你还不是很清楚我在说什么,可以看POIFS Browser打开test.xls文件后的截图:

image

你会发现只有Workbook目录,其他什么都没有,但事实上一个正常的xls文件,比如说Excel生成的xls文件是类似下面的结构:

image

是不是多出来DocumentSummaryInformation和SummaryInformation两个头?很多人可能对DocumentSummaryInformation和SummaryInformation很陌生,可能第一次听说这玩意,没事,这很正常,因为普通用户很少会去使用这些东西,但它们其实比想象中有用。

image

请看上图中的信息,如作者、标题、标记、备注、主题等信息,其实这些信息都是存储在DocummentSummaryInformation和SummaryInformation里面的,这么一说我想大家应该明白了吧,这些信息是为了快速提取文件信息准备。在Windows XP中,也有对应的查看和修改界面,只是没有Vista这么方便,如下所示:

propertysetwindow1-thumb

这恐怕也是很多人对于这些信息漠不关心的原因吧,因为没有人愿意通过 右击文件->属性 这样复杂的操作去查看一些摘要信息。

 

提示

DocummentSummaryInformation和SummaryInformation并不是Office文件的专利,只要是OLE2格式,都可以拥有这两个头信息,主要目的就是为了在没有完整读取文件数据的情况下获得文件的摘要信息,同时也可用作桌面搜素的依据。要了解DocummentSummaryInformation的全部属性请见http://msdn.microsoft.com/en-us/library/aa380374(VS.85).aspx;要了解SummaryInformation的全部属性请见http://msdn.microsoft.com/en-us/library/aa369794(VS.85).aspx

 

好了,说到这里,我想大家对于接下来我们要创建的内容有了初步的认识,下面我们就马上动手创建。

首先引用以下这些命名空间:

using NPOI.HSSF.UserModel;
using NPOI.HPSF;
using NPOI.POIFS.FileSystem;

其中与DocummentSummaryInformation和SummaryInformation密切相关的是HPSF命名空间。

首先创建Workbook

HSSFWorkbook hssfworkbook = new HSSFWorkbook();

然后创建DocumentSummaryInformation

DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
dsi.Company = "NPOI Team";

再创建SummaryInformation

SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
si.Subject = "NPOI SDK Example";

因为是范例,这里仅各设置了一个属性,其他都没有设置。

现在我们把创建好的对象赋给Workbook,这样才能保证这些信息被写入文件。

hssfworkbook.DocumentSummaryInformation = dsi;
hssfworkbook.SummaryInformation = si;

最后和2.1.1节一样,我们把Workbook通过FileStream写入文件。

发表在 C# | 留下评论

NPOI 1.2 教程 – 2.1.1 创建Workbook和Sheet

 转载:http://tonyqus.sinaapp.com/archives/501

创建Workbook说白了就是创建一个Excel文件,当然在NPOI中更准确的表示是在内存中创建一个Workbook对象流。

本节作为第2章的开篇章节,将做较为详细的讲解,以帮助NPOI的学习者更好的理解NPOI的组成和使用。

NPOI.HSSF是专门负责Excel BIFF格式的命名空间,供开发者使用的对象主要位于NPOI.HSSF.UserModel和NPOI.HSSF.Util命名空间下,下面我们要讲到的Workbook的创建用的就是NPOI.HSSF.UserModel.HSSFWorkbook类,这个类负责创建.xls文档。

在开始创建Workbook之前,我们先要在项目中引用一些必要的NPOI assembly,如下所示:

NPOI.dll

NPOI.POIFS.dll

NPOI.HSSF.dll

NPOI.Util.dll

要创建一个新的xls文件其实很简单,只要我们初始化一个新的HSSFWorkbook实例就行了,如下所示:

1
2
3
using NPOI.HSSF.UserModel;
...
HSSFWorkbook hssfworkbook = new HSSFWorkbook();

是不是很方便啊,没有任何参数或设置,但这么创建有一些限制,这样创建出来的Workbook在Excel中打开是会报错的,因为Excel规定一个Workbook必须至少带1个Sheet,这也是为什么在Excel界面中,新建一个Workbook默认都会新建3个Sheet。所以必须加入下面的创建Sheet的代码才能保证生成的文件正常:

1
HSSFSheet sheet = hssfworkbook.CreateSheet("new sheet");

如果要创建标准的Excel文件,即拥有3个Sheet,可以用下面的代码:

1
2
3
hssfworkbook.CreateSheet("Sheet1");
hssfworkbook.CreateSheet("Sheet2");
hssfworkbook.CreateSheet("Sheet3");

最后就是把这个HSSFWorkbook实例写入文件了,代码也很简单,如下所示:

1
2
3
FileStream file = new FileStream("test.xls", FileMode.Create);
hssfworkbook.Write(file);
file.Close();

这里假设文件名是test.xls,,在创建完FileStream之后,直接调用HSSFWorkbook类的Write方法就可以了。

最后你可以打开test.xls文件确认一下,是不是有3个空的Sheet。

发表在 C# | 留下评论

C#读取Excel的第三方插件Aspose.Cells

不需要Office就可以读写Excle的xls,xlsx等格式的文件,使用非常简单。

string fileName = “D:\\test.xls”;
Workbook book = new Workbook(fileName);

//一些操作

book.Save(fileName);//保存文件

下载:http://yun.baidu.com/share/link?shareid=1411549812&uk=721859502

发表在 C# | 留下评论

添加扩展数据XDATA

转载:http://blog.csdn.net/yuandingmao/article/details/5563452

使用ResultBuffer类 
        在ObjectARX中,resbuf结构给AutoCAD专门数据提供了一个灵活的存储器。在托管API中,这个结构被映射在Autodesk.AutoCAD.DatabaseServices.ResultBuffer类中。
     一个ResultBuffer类对象使用的方法与resbuf数据链相同。你要定义一个ResultBuffer并使它产生一系列的数据对。每一对数据由一个数据类型描述和一个值组成。在托管API中,
        这些数据对是Autodesk.AutoCAD.DatabaseServices.TypedValue类的实例。这个类实现的功能与resbuf结构的restype和resval成员一样。 
     TypedValue.TypeCode属性是一个16位的整数值,它表示TypedValue.Value属性的数据类型。可以使用的TypeCode值取决于ResultBuffer实例的具体使用情况。
        例如,适合于xrecord定义的TypeCode的值就不一定适用于xdata。Autodesk.AutoCAD.DatabaseServices.DxfCode枚举定义的代码精确地描述了所有可能的ResultBuffer数据类型的范围。
    因为TypedValue.Value属性与System.Object的一个实例相对应,所以它可以包含任何数据类型。但是,Value数据必须与TypeCode所表示的类一致,以保证结果的可用性。
    你可以通过给ResultBuffer的构造函数传递一个TypedValue对象数组来提前产生一个ResultBuffer,或者可以先构造一个空的ResultBuffer,
        然后通过调用ResultBuffer.Add()方法来加入新的TypedValue对象。

 #region 添加扩展数据XDATA
        /// <summary>
        /// 添加扩展数据xdata
        /// </summary>
        /// <param name=”ent”>被填充的实体</param>
        /// <param name=”obj”>填充的数据</param>
        /// <param name=”regapptablename”>regapptabl名称</param>
        /// <returns></returns>
        public Autodesk.AutoCAD.DatabaseServices.Entity AddXData(Autodesk.AutoCAD.DatabaseServices.Entity ent,Object obj,string regapptablename)
        {
           
            Autodesk.AutoCAD.DatabaseServices.ObjectId objId = ent.ObjectId;
            Autodesk.AutoCAD.DatabaseServices.Database db = Autodesk.AutoCAD.DatabaseServices.HostApplicationServices.WorkingDatabase;
             Autodesk.AutoCAD.DatabaseServices.Entity retEntity ;
            using (Autodesk.AutoCAD.DatabaseServices.Transaction trans = db.TransactionManager.StartTransaction())
            {
                retEntity = trans.GetObject(ent.ObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite) as Autodesk.AutoCAD.DatabaseServices.Entity;
                
                Autodesk.AutoCAD.DatabaseServices.RegAppTable appTbl = trans.GetObject(db.RegAppTableId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite) as Autodesk.AutoCAD.DatabaseServices.RegAppTable;
                if (!appTbl.Has(regapptablename))
                {
                    Autodesk.AutoCAD.DatabaseServices.RegAppTableRecord appTblRcd = new Autodesk.AutoCAD.DatabaseServices.RegAppTableRecord();
                    appTblRcd.Name = regapptablename;
                    appTbl.Add(appTblRcd);
                    trans.AddNewlyCreatedDBObject(appTblRcd, true);
                }
                Autodesk.AutoCAD.DatabaseServices.ResultBuffer resBuf = new Autodesk.AutoCAD.DatabaseServices.ResultBuffer();

                
                // 先必须要将注册表添加到buffer里
                resBuf.Add(new Autodesk.AutoCAD.DatabaseServices.TypedValue((int)Autodesk.AutoCAD.DatabaseServices.DxfCode.ExtendedDataRegAppName, regapptablename));
                // 再将数据或对象加到buffer里 注意typecode 要是1000-1071里
                resBuf.Add(new Autodesk.AutoCAD.DatabaseServices.TypedValue((int)Autodesk.AutoCAD.DatabaseServices.DxfCode.ExtendedDataAsciiString, obj));//将某个对象添加到扩展数据中

                ent.XData = resBuf;
                trans.Commit();
            }

            return retEntity;

        }
        #endregion

        #region 获取扩展数据
        /// <summary>
        /// 获取扩展数据集合
        /// </summary>
        /// <param name=”ent”>实体</param>
        /// <returns>返回System.Collections.IEnumerator</returns>
        public System.Collections.IEnumerator GetXData(Autodesk.AutoCAD.DatabaseServices.Entity ent)
        {
            Autodesk.AutoCAD.EditorInput.Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;

            System.Collections.IEnumerator itor;
            Autodesk.AutoCAD.DatabaseServices.Database db = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;
            using (Autodesk.AutoCAD.DatabaseServices.Transaction trans = db.TransactionManager.StartTransaction())
            {
                ent = (Autodesk.AutoCAD.DatabaseServices.Entity)trans.GetObject(ent.ObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead);
                Autodesk.AutoCAD.DatabaseServices.ResultBuffer resBuf = ent.XData;
                if (resBuf != null)
                {
                    //获取IEnumerator
                    itor = resBuf.GetEnumerator();

                }
                else
                    itor = null;
            }
            return itor;
        }

        /// <summary>
        /// 获取实体的扩展数据
        /// </summary>
        /// <param name=”ent”>实体</param>
        /// <returns>返回泛型的对象集</returns>
        public List<System.Object> GetXDataList(Autodesk.AutoCAD.DatabaseServices.Entity ent)
        {
            Autodesk.AutoCAD.EditorInput.Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;

            List<System.Object> objs = new List<System.Object>();
            Autodesk.AutoCAD.DatabaseServices.Database db = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;
            using (Autodesk.AutoCAD.DatabaseServices.Transaction trans = db.TransactionManager.StartTransaction())
            {
               ent = (Autodesk.AutoCAD.DatabaseServices.Entity)trans.GetObject(ent.ObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead);
              
                Autodesk.AutoCAD.DatabaseServices.ResultBuffer resBuf = ent.XData;
                if (resBuf != null)
                {                   
                    System.Collections.IEnumerator itor = resBuf.GetEnumerator();
                    while (itor.MoveNext())
                    {
                        Autodesk.AutoCAD.DatabaseServices.TypedValue tmpVal = (Autodesk.AutoCAD.DatabaseServices.TypedValue)itor.Current;
                        objs.Add(tmpVal.Value);
                    }
                }
                trans.Commit();
            }
            return objs;
        }
        #endregion

发表在 ObjectArx | 留下评论

C# String.Format格式说明

C#格式化数值结果表

字符

说明

示例

输出

C 货币 string.Format(“{0:C3}”, 2) $2.000
D 十进制 string.Format(“{0:D3}”, 2) 002
E 科学计数法 1.20E+001 1.20E+001
G 常规 string.Format(“{0:G}”, 2) 2
N 用分号隔开的数字 string.Format(“{0:N}”, 250000) 250,000.00
X 十六进制 string.Format(“{0:X000}”, 12) C


string.Format(“{0:000.000}”, 12.2) 012.200

Strings

There really isn’t any formatting within a strong, beyond it’s alignment. Alignment works for any argument being printed in a String.Format call.

 

Sample Generates
String.Format(“->{1,10}<-“, “Hello”); -> Hello<-
String.Format(“->{1,-10}<-“, “Hello”); ->Hello <-

Numbers

Basic number formatting specifiers:

 

Specifier Type Format Output
(Passed
Double 1.42)
Output
(Passed
Int -12400)
c Currency {0:c} $1.42 -$12,400
d Decimal (Whole number) {0:d} System.
FormatException
-12400
e Scientific {0:e} 1.420000e+000 -1.240000e+004
f Fixed point {0:f} 1.42 -12400.00
g General {0:g} 1.42 -12400
n Number with commas for thousands {0:n} 1.42 -12,400
r Round trippable {0:r} 1.42 System.
FormatException
x Hexadecimal {0:x4} System.
FormatException
cf90

Custom number formatting:

 

Specifier Type Example Output (Passed Double 1500.42) Note
0 Zero placeholder {0:00.0000} 1500.4200 Pads with zeroes.
# Digit placeholder {0:(#).##} (1500).42  
. Decimal point {0:0.0} 1500.4  
, Thousand separator {0:0,0} 1,500 Must be between two zeroes.
,. Number scaling {0:0,.} 2 Comma adjacent to Period scales by 1000.
% Percent {0:0%} 150042% Multiplies by 100, adds % sign.
e Exponent placeholder {0:00e+0} 15e+2 Many exponent formats available.
; Group separator see below    

The group separator is especially useful for formatting currency values which require that negative values be enclosed in parentheses. This currency formatting example at the bottom of this document makes it obvious:

Dates

Note that date formatting is especially dependant on the system’s regional settings; the example strings here are from my local locale.

 

Specifier Type Example (Passed System.DateTime.Now)
d Short date 10/12/2002
D Long date December 10, 2002
t Short time 10:11 PM
T Long time 10:11:29 PM
f Full date & time December 10, 2002 10:11 PM
F Full date & time (long) December 10, 2002 10:11:29 PM
g Default date & time 10/12/2002 10:11 PM
G Default date & time (long) 10/12/2002 10:11:29 PM
M Month day pattern December 10
r RFC1123 date string Tue, 10 Dec 2002 22:11:29 GMT
s Sortable date string 2002-12-10T22:11:29
u Universal sortable, local time 2002-12-10 22:13:50Z
U Universal sortable, GMT December 11, 2002 3:13:50 AM
Y Year month pattern December, 2002

The ‘U’ specifier seems broken; that string certainly isn’t sortable.

Custom date formatting:

 

Specifier Type Example Example Output
dd Day {0:dd} 10
ddd Day name {0:ddd} Tue
dddd Full day name {0:dddd} Tuesday
f, ff, … Second fractions {0:fff} 932
gg, … Era {0:gg} A.D.
hh 2 digit hour {0:hh} 10
HH 2 digit hour, 24hr format {0:HH} 22
mm Minute 00-59 {0:mm} 38
MM Month 01-12 {0:MM} 12
MMM Month abbreviation {0:MMM} Dec
MMMM Full month name {0:MMMM} December
ss Seconds 00-59 {0:ss} 46
tt AM or PM {0:tt} PM
yy Year, 2 digits {0:yy} 02
yyyy Year {0:yyyy} 2002
zz Timezone offset, 2 digits {0:zz} -05
zzz Full timezone offset {0:zzz} -05:00
: Separator {0:hh:mm:ss} 10:43:20
/ Separator {0:dd/MM/yyyy} 10/12/2002

Enumerations

 

Specifier Type
g Default (Flag names if available, otherwise decimal)
f Flags always
d Integer always
x Eight digit hex.

Some Useful Examples

String.Format(“{0:$#,##0.00;($#,##0.00);Zero}”, value);

This will output “$1,240.00” if passed 1243.50. It will output the same format but in parentheses if the number is negative, and will output the string “Zero” if the number is zero.

String.Format(“{0:(###) ###-####}”, 18005551212);

This will output “(800) 555-1212”.

 

变量.ToString()
字符型转换 转为字符串
12345.ToString(“n”); //生成 12,345.00
12345.ToString(“C”); //生成 ¥12,345.00
12345.ToString(“e”); //生成 1.234500e+004
12345.ToString(“f4”); //生成 12345.0000
12345.ToString(“x”); //生成 3039 (16进制)
12345.ToString(“p”); //生成 1,234,500.00%

发表在 C# | 留下评论

[ARX.Net]使用Jig

上一篇文章介绍了如何定义一个Jig

浅谈JIG之EntityJig&DrawJig

这里我们来使用它。

 DrawJigEnt  jig = new DrawJigEnt(ents);
            Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
            PromptResult pr = ed.Drag(jig);

和C++里面不同,这里是通过Editor类来调用的。

发表在 ObjectArx.Net | 留下评论

浅谈JIG之EntityJig&DrawJig

转载:http://www.cnblogs.com/wangyong/archive/2010/01/20/1652412.html

在CAD的二次开发中,有时会使用JIG技术来实现操作的动态性、交互,最常见的比如说是在CAD中定制自己的移动和复制,当然要保持CAD中原有的动态显示效果。

      在JIG中我们可以继承EntityJig和DrawJig,对于这两个类,那这两个类有什么区别呢?他们的使用场合又有什么区别呢?

     其实,他们之间在操作一些简单的实体的时候是没有多大区别的,硬要说区别的话,那就是在实现一个相同功能时DrawJig比EntityJig的代码简单一些。(注意:是指在操作简单的实体的时候,比如实体的数量就一个)。

        EntityJig:一般用于图元实体的拖动,要求先生成实体Entity

        protected override bool Update()
        {
            throw new NotImplementedException();
        }

        protected override SamplerStatus Sampler(JigPrompts prompts)
        {
            throw new NotImplementedException();
        }

        DrawJig:一般用于复杂图形的拖动

       protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw)
        {
            throw new NotImplementedException();
        }

        protected override SamplerStatus Sampler(JigPrompts prompts)
        {
            throw new NotImplementedException();
        }

      在拖动一个实体的时候,不管是用EntityJig还是DrawJig效果都一样,但是当我们在处理多个实体的移动,我们要求鼠标可以实时动态显示要拖动的多个实体,这点,EntityJig却无法实现了,但如果是DrawJig却很容易实现。

而且对于动态生成实体(比如指定一个圆心,动态生成一个圆),用DrawJig中的WorlDraw可以灵活控制实现生成。

  相比之下,是不是发现DrawJig优胜于EntityJig(个人理解).

  下面贴出上图实现的代码:

代码
#region DrawJig动态拖动多个实体
    public class DrawJigEnt : DrawJig
    {
        //变量
        Point3d oldPt;//实体移动之前的位置
        Point3d newPt;//实体移动之后的位置
        Vector3d v;//实体移动的向量

        List<Entity> ents = new List<Entity>();
        List<Point3d> oldPts = new List<Point3d>();
        public DrawJigEnt(List<Entity> ents)
        {
            oldPt = Point3d.Origin;
            newPt = Point3d.Origin;
            v = new Vector3d();
            this.ents = ents;

            Autodesk.AutoCAD.DatabaseServices.Entity ent = ents[0];
            if (ent is BlockReference)
            {
                BlockReference br = ent as BlockReference;
                oldPt = br.Position;
            }

            for (int i = 1; i < ents.Count; i++)
            {
                if (ents[i] is BlockReference)
                {
                    BlockReference br = ents[i] as BlockReference;
                    oldPts.Add(br.Position);
                }
            }
        }

        //更新
        protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw)
        {
            Entity ent = ents[0];
            ent.UpgradeOpen();
            if (ent is BlockReference)
            {
                BlockReference br = ent as BlockReference;
                br.Position = newPt;
                draw.Geometry.Draw(br);
            }

            v = newPt.GetVectorTo(oldPt);
           
            for(int i =1;i<ents.Count;i++)
            {
                Entity entity = ents[i];
                entity.UpgradeOpen();
                if (entity is BlockReference)
                {
                    BlockReference br = entity as BlockReference;
                    br.Position = oldPts[i – 1] + v;
                    draw.Geometry.Draw(entity);
                }
            }

            return true;
        }
        //取样函数
        protected override SamplerStatus Sampler(JigPrompts prompts)
        {
            JigPromptOptions opt = new JigPromptOptions();
            opt.UserInputControls = UserInputControls.Accept3dCoordinates | UserInputControls.NoNegativeResponseAccepted | UserInputControls.NullResponseAccepted;
            opt.UseBasePoint = true;
            opt.Cursor = CursorType.RubberBand;
            opt.BasePoint = oldPt;
            opt.Message = “选择移动到的终点”;

            PromptPointResult res = prompts.AcquirePoint(opt);
            if (PromptStatus.OK == res.Status)
            {
                if (res.Value == newPt)
                {
                    return SamplerStatus.NoChange;
                }
                newPt = res.Value;
            }
            else
            {
                return SamplerStatus.Cancel;
            }
            return SamplerStatus.OK;
        }
    }
    #endregion

 

发表在 ObjectArx.Net | 留下评论