Showder's profile→↗↘↑篆刻岁月&♂↙↖↓←=∑(品味人生+忍耐...PhotosBlogListsMore ![]() | Help |
|
|
August 09 USB相关服务要使用USB接口,必须有以下服务启动:
Messenger |_NetBIOS Interface |_Plug and Play |_Remote Procedure Call (RPC) |_Workstation 将所有的服务启动后,可以正常使用USB(这里使用的是MOTO 手机的USB) June 06 键盘上字符读法大全网上来的,还是保存起来,比较好找. # hash/sharp
` backquote 反引号
< is less than
:arrow: α Α alpha ['ælfa] 'exclam'='!' November 12 HTTP1.1状态字『转』HTTP1.1状态字(原版)- -part of Hypertext Transfer Protocol -- HTTP/1.1 RFC 2616 Fielding, et al. 10 Status Code DefinitionsEach Status-Code is described below, including a description of which method(s) it can follow and any metainformation required in the response. 10.1 Informational 1xxThis class of status code indicates a provisional response, consisting only of the Status-Line and optional headers, and is terminated by an empty line. There are no required headers for this class of status code. Since HTTP/1.0 did not define any 1xx status codes, servers MUST NOT send a 1xx response to an HTTP/1.0 client except under experimental conditions. A client MUST be prepared to accept one or more 1xx status responses prior to a regular response, even if the client does not expect a 100 (Continue) status message. Unexpected 1xx status responses MAY be ignored by a user agent. Proxies MUST forward 1xx responses, unless the connection between the proxy and its client has been closed, or unless the proxy itself requested the generation of the 1xx response. (For example, if a proxy adds a "Expect: 100-continue" field when it forwards a request, then it need not forward the corresponding 100 (Continue) response(s).) 10.1.1 100 ContinueThe client SHOULD continue with its request. This interim response is used to inform the client that the initial part of the request has been received and has not yet been rejected by the server. The client SHOULD continue by sending the remainder of the request or, if the request has already been completed, ignore this response. The server MUST send a final response after the request has been completed. See section 8.2.3 for detailed discussion of the use and handling of this status code. 10.1.2 101 Switching ProtocolsThe server understands and is willing to comply with the client's request, via the Upgrade message header field (section 14.42), for a change in the application protocol being used on this connection. The server will switch protocols to those defined by the response's Upgrade header field immediately after the empty line which terminates the 101 response. The protocol SHOULD be switched only when it is advantageous to do so. For example, switching to a newer version of HTTP is advantageous over older versions, and switching to a real-time, synchronous protocol might be advantageous when delivering resources that use such features. 10.2 Successful 2xxThis class of status code indicates that the client's request was successfully received, understood, and accepted. 10.2.1 200 OKThe request has succeeded. The information returned with the response is dependent on the method used in the request, for example: GET an entity corresponding to the requested resource is sent in the response; HEAD the entity-header fields corresponding to the requested resource are sent in the response without any message-body; POST an entity describing or containing the result of the action; TRACE an entity containing the request message as received by the end server. 10.2.2 201 CreatedThe request has been fulfilled and resulted in a new resource being created. The newly created resource can be referenced by the URI(s) returned in the entity of the response, with the most specific URI for the resource given by a Location header field. The response SHOULD include an entity containing a list of resource characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. The origin server MUST create the resource before returning the 201 status code. If the action cannot be carried out immediately, the server SHOULD respond with 202 (Accepted) response instead. A 201 response MAY contain an ETag response header field indicating the current value of the entity tag for the requested variant just created, see section 14.19. 10.2.3 202 AcceptedThe request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place. There is no facility for re-sending a status code from an asynchronous operation such as this. The 202 response is intentionally non-committal. Its purpose is to allow a server to accept a request for some other process (perhaps a batch-oriented process that is only run once per day) without requiring that the user agent's connection to the server persist until the process is completed. The entity returned with this response SHOULD include an indication of the request's current status and either a pointer to a status monitor or some estimate of when the user can expect the request to be fulfilled. 10.2.4 203 Non-Authoritative InformationThe returned metainformation in the entity-header is not the definitive set as available from the origin server, but is gathered from a local or a third-party copy. The set presented MAY be a subset or superset of the original version. For example, including local annotation information about the resource might result in a superset of the metainformation known by the origin server. Use of this response code is not required and is only appropriate when the response would otherwise be 200 (OK). 10.2.5 204 No ContentThe server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation. The response MAY include new or updated metainformation in the form of entity-headers, which if present SHOULD be associated with the requested variant. If the client is a user agent, it SHOULD NOT change its document view from that which caused the request to be sent. This response is primarily intended to allow input for actions to take place without causing a change to the user agent's active document view, although any new or updated metainformation SHOULD be applied to the document currently in the user agent's active view. The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields. 10.2.6 205 Reset ContentThe server has fulfilled the request and the user agent SHOULD reset the document view which caused the request to be sent. This response is primarily intended to allow input for actions to take place via user input, followed by a clearing of the form in which the input is given so that the user can easily initiate another input action. The response MUST NOT include an entity. 10.2.7 206 Partial ContentThe server has fulfilled the partial GET request for the resource. The request MUST have included a Range header field (section 14.35) indicating the desired range, and MAY have included an If-Range header field (section 14.27) to make the request conditional. The response MUST include the following header fields: - Either a Content-Range header field (section 14.16) indicating - Date - ETag and/or Content-Location, if the header would have been sent - Expires, Cache-Control, and/or Vary, if the field-value might If the 206 response is the result of an If-Range request that used a strong cache validator (see section 13.3.3), the response SHOULD NOT include other entity-headers. If the response is the result of an If-Range request that used a weak validator, the response MUST NOT include other entity-headers; this prevents inconsistencies between cached entity-bodies and updated headers. Otherwise, the response MUST include all of the entity-headers that would have been returned with a 200 (OK) response to the same request. A cache MUST NOT combine a 206 response with other previously cached content if the ETag or Last-Modified headers do not match exactly, see 13.5.4. A cache that does not support the Range and Content-Range headers MUST NOT cache 206 (Partial) responses. 10.3 Redirection 3xxThis class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request. The action required MAY be carried out by the user agent without interaction with the user if and only if the method used in the second request is GET or HEAD. A client SHOULD detect infinite redirection loops, since such loops generate network traffic for each redirection. Note: previous versions of this specification recommended a 10.3.1 300 Multiple ChoicesThe requested resource corresponds to any one of a set of representations, each with its own specific location, and agent- driven negotiation information (section 12) is being provided so that the user (or user agent) can select a preferred representation and redirect its request to that location. Unless it was a HEAD request, the response SHOULD include an entity containing a list of resource characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content- Type header field. Depending upon the format and the capabilities of the user agent, selection of the most appropriate choice MAY be performed automatically. However, this specification does not define any standard for such automatic selection. If the server has a preferred choice of representation, it SHOULD include the specific URI for that representation in the Location field; user agents MAY use the Location field value for automatic redirection. This response is cacheable unless indicated otherwise. 10.3.2 301 Moved PermanentlyThe requested resource has been assigned a new permanent URI and any future references to this resource SHOULD use one of the returned URIs. Clients with link editing capabilities ought to automatically re-link references to the Request-URI to one or more of the new references returned by the server, where possible. This response is cacheable unless indicated otherwise. The new permanent URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s). If the 301 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. Note: When automatically redirecting a POST request after 10.3.3 302 FoundThe requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field. The temporary URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s). If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. Note: RFC 1945 and RFC 2068 specify that the client is not allowed 10.3.4 303 See OtherThe response to the request can be found under a different URI and SHOULD be retrieved using a GET method on that resource. This method exists primarily to allow the output of a POST-activated script to redirect the user agent to a selected resource. The new URI is not a substitute reference for the originally requested resource. The 303 response MUST NOT be cached, but the response to the second (redirected) request might be cacheable. The different URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s). Note: Many pre-HTTP/1.1 user agents do not understand the 303 10.3.5 304 Not ModifiedIf the client has performed a conditional GET request and access is allowed, but the document has not been modified, the server SHOULD respond with this status code. The 304 response MUST NOT contain a message-body, and thus is always terminated by the first empty line after the header fields. The response MUST include the following header fields: - Date, unless its omission is required by section 14.18.1 If a clockless origin server obeys these rules, and proxies and clients add their own Date to any response received without one (as already specified by [RFC 2068], section 14.19), caches will operate correctly. - ETag and/or Content-Location, if the header would have been sent - Expires, Cache-Control, and/or Vary, if the field-value might If the conditional GET used a strong cache validator (see section 13.3.3), the response SHOULD NOT include other entity-headers. Otherwise (i.e., the conditional GET used a weak validator), the response MUST NOT include other entity-headers; this prevents inconsistencies between cached entity-bodies and updated headers. If a 304 response indicates an entity not currently cached, then the cache MUST disregard the response and repeat the request without the conditional. If a cache uses a received 304 response to update a cache entry, the cache MUST update the entry to reflect any new field values given in the response. 10.3.6 305 Use ProxyThe requested resource MUST be accessed through the proxy given by the Location field. The Location field gives the URI of the proxy. The recipient is expected to repeat this single request via the proxy. 305 responses MUST only be generated by origin servers. Note: RFC 2068 was not clear that 305 was intended to redirect a 10.3.7 306 (Unused)The 306 status code was used in a previous version of the specification, is no longer used, and the code is reserved. 10.3.8 307 Temporary RedirectThe requested resource resides temporarily under a different URI. Since the redirection MAY be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field. The temporary URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s) , since many pre-HTTP/1.1 user agents do not understand the 307 status. Therefore, the note SHOULD contain the information necessary for a user to repeat the original request on the new URI. If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. 10.4 Client Error 4xxThe 4xx class of status code is intended for cases in which the client seems to have erred. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. These status codes are applicable to any request method. User agents SHOULD display any included entity to the user. If the client is sending data, a server implementation using TCP SHOULD be careful to ensure that the client acknowledges receipt of the packet(s) containing the response, before the server closes the input connection. If the client continues sending data to the server after the close, the server's TCP stack will send a reset packet to the client, which may erase the client's unacknowledged input buffers before they can be read and interpreted by the HTTP application. 10.4.1 400 Bad RequestThe request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications. 10.4.2 401 UnauthorizedThe request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user SHOULD be presented the entity that was given in the response, since that entity might include relevant diagnostic information. HTTP access authentication is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43]. 10.4.3 402 Payment RequiredThis code is reserved for future use. 10.4.4 403 ForbiddenThe server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead. 10.4.5 404 Not FoundThe server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable. 10.4.6 405 Method Not AllowedThe method specified in the Request-Line is not allowed for the resource identified by the Request-URI. The response MUST include an Allow header containing a list of valid methods for the requested resource. 10.4.7 406 Not AcceptableThe resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request. Unless it was a HEAD request, the response SHOULD include an entity containing a list of available entity characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. Depending upon the format and the capabilities of the user agent, selection of the most appropriate choice MAY be performed automatically. However, this specification does not define any standard for such automatic selection. Note: HTTP/1.1 servers are allowed to return responses which are If the response could be unacceptable, a user agent SHOULD temporarily stop receipt of more data and query the user for a decision on further actions. 10.4.8 407 Proxy Authentication RequiredThis code is similar to 401 (Unauthorized), but indicates that the client must first authenticate itself with the proxy. The proxy MUST return a Proxy-Authenticate header field (section 14.33) containing a challenge applicable to the proxy for the requested resource. The client MAY repeat the request with a suitable Proxy-Authorization header field (section 14.34). HTTP access authentication is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43]. 10.4.9 408 Request TimeoutThe client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time. 10.4.10 409 ConflictThe request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required. Conflicts are most likely to occur in response to a PUT request. For example, if versioning were being used and the entity being PUT included changes to a resource which conflict with those made by an earlier (third-party) request, the server might use the 409 response to indicate that it can't complete the request. In this case, the response entity would likely contain a list of the differences between the two versions in a format defined by the response Content-Type. 10.4.11 410 GoneThe requested resource is no longer available at the server and no forwarding address is known. This condition is expected to be considered permanent. Clients with link editing capabilities SHOULD delete references to the Request-URI after user approval. If the server does not know, or has no facility to determine, whether or not the condition is permanent, the status code 404 (Not Found) SHOULD be used instead. This response is cacheable unless indicated otherwise. The 410 response is primarily intended to assist the task of web maintenance by notifying the recipient that the resource is intentionally unavailable and that the server owners desire that remote links to that resource be removed. Such an event is common for limited-time, promotional services and for resources belonging to individuals no longer working at the server's site. It is not necessary to mark all permanently unavailable resources as "gone" or to keep the mark for any length of time -- that is left to the discretion of the server owner. 10.4.12 411 Length RequiredThe server refuses to accept the request without a defined Content- Length. The client MAY repeat the request if it adds a valid Content-Length header field containing the length of the message-body in the request message. 10.4.13 412 Precondition FailedThe precondition given in one or more of the request-header fields evaluated to false when it was tested on the server. This response code allows the client to place preconditions on the current resource metainformation (header field data) and thus prevent the requested method from being applied to a resource other than the one intended. 10.4.14 413 Request Entity Too LargeThe server is refusing to process a request because the request entity is larger than the server is willing or able to process. The server MAY close the connection to prevent the client from continuing the request. If the condition is temporary, the server SHOULD include a Retry- After header field to indicate that it is temporary and after what time the client MAY try again. 10.4.15 414 Request-URI Too LongThe server is refusing to service the request because the Request-URI is longer than the server is willing to interpret. This rare condition is only likely to occur when a client has improperly converted a POST request to a GET request with long query information, when the client has descended into a URI "black hole" of redirection (e.g., a redirected URI prefix that points to a suffix of itself), or when the server is under attack by a client attempting to exploit security holes present in some servers using fixed-length buffers for reading or manipulating the Request-URI. 10.4.16 415 Unsupported Media TypeThe server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method. 10.4.17 416 Requested Range Not SatisfiableA server SHOULD return a response with this status code if a request included a Range request-header field (section 14.35), and none of the range-specifier values in this field overlap the current extent of the selected resource, and the request did not include an If-Range request-header field. (For byte-ranges, this means that the first- byte-pos of all of the byte-range-spec values were greater than the current length of the selected resource.) When this status code is returned for a byte-range request, the response SHOULD include a Content-Range entity-header field specifying the current length of the selected resource (see section 14.16). This response MUST NOT use the multipart/byteranges content- type. 10.4.18 417 Expectation FailedThe expectation given in an Expect request-header field (see section 14.20) could not be met by this server, or, if the server is a proxy, the server has unambiguous evidence that the request could not be met by the next-hop server. 10.5 Server Error 5xxResponse status codes beginning with the digit "5" indicate cases in which the server is aware that it has erred or is incapable of performing the request. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. User agents SHOULD display any included entity to the user. These response codes are applicable to any request method. 10.5.1 500 Internal Server ErrorThe server encountered an unexpected condition which prevented it from fulfilling the request. 10.5.2 501 Not ImplementedThe server does not support the functionality required to fulfill the request. This is the appropriate response when the server does not recognize the request method and is not capable of supporting it for any resource. 10.5.3 502 Bad GatewayThe server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request. 10.5.4 503 Service UnavailableThe server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay. If known, the length of the delay MAY be indicated in a Retry-After header. If no Retry-After is given, the client SHOULD handle the response as it would for a 500 response. Note: The existence of the 503 status code does not imply that a 10.5.5 504 Gateway TimeoutThe server, while acting as a gateway or proxy, did not receive a timely response from the upstream server specified by the URI (e.g. HTTP, FTP, LDAP) or some other auxiliary server (e.g. DNS) it needed to access in attempting to complete the request. Note: Note to implementors: some deployed proxies are known to 10.5.6 505 HTTP Version Not SupportedThe server does not support, or refuses to support, the HTTP protocol version that was used in the request message. The server is indicating that it is unable or unwilling to complete the request using the same major version as the client, as described in section 3.1, other than with this error message. The response SHOULD contain an entity describing why that version is not supported and what other protocols are supported by that server. May 23 所谓的Web2.0前100强Web2.0 也点了一段不短的时间了,05-06也炒的着实火了一把。
现在发展成什么样了?还没来得及仔细跟进了解呢,这就出来了Web2.0 100名单?世道发展太快...
赶紧,不能落后了,先补上一课...
互联网协会与IDGVC发布Web2.0 100名单:
3月28日,中国互联网协会与IDGVC合作发布“中国互联网Web2.0 100”,以下为获得Web2.0 100的企业名单:
2006中国互联网大会组委会
中国互联网协会交流与发展中心 mop.com排老大应该是无可非议的!呵呵,太有名了~ 在名单中发现了赶集!~ 59!就是www.google.cn借用ICP的那个网站?
XX几句:
名单中的半数还是听过的,上过的也有些,大概30个左右。有的倒是真的有点特色,如:豆瓣,客齐集(现在上去根本就没有当初的样子了~),Donews,CSDN(呵呵,是程序员都应该知道~),365Key,当然,不是说其他没有了,我只是说我看过的这些中,这几个网站还比较适合我。 另外,奇虎作为论坛搜索,自然有特色,东西也多了,刚开始的时候少的可怜,搜索出来的东西看的出来,更新也很快的。。。最早用论坛搜索的时候搜索出来的东西都不知道是什么...感觉如果要看色情、暴力之类的倒是最佳选择,今天看了下,好像不错了,没有以前那些东西了,过滤了吧~~而且在某些方面,好像能够看到Baidu的影子,搜索完,看看结果页面的下面的一排关键字(相关搜索 )...发现了没?^_^。。。不过已经非常不错了,看来Qihoo发起的论坛联盟还是很有效果滴... April 16 HTML<代码(dài mǎ)>分析器(fēn xī qì)--HTML <Code> AnalyzerHTML <Code> Analyzer
今天发现Google的图片换了,上面有个中文名字,叫“谷歌”,想必是最流行的中文名字已经被人注册咯,有意思,【图片地址】
经过昨天晚上的初步处理 HTML代码处理已经有些雏形,今天也处理了一下,昨天的问题已经得到一些解决。 现在问题是: 1.对于多代码的时候,仍然有些格式不能很好的调整过来 <%#%><%=%>之类代码没有处理
2.速度不敢恭维,烂啊,一个80K左右的文件要10S以上,肯定不行,别人的程序快的多了
3.设计过于呆板,没有利用到更好的处理方法,大多数东西需要自己去处理
...
鉴于此:
1.寻找更好的方法解决读取HTML代码的问题,有可能方式:
1>。用正则表达式来分析代码,这样不容易出现问题
2>。类似XML的处理方式
3>。双栈处理
至于到底用那种方式,现在没有时间思考了,先写下来,到时候有时间再来弄她。
2.速度相信在第一点得以处理的前提下,应该可以得到一定的提升
3.生成Dll形式,以后可以在其他地方使用。
耦合再低点,内聚再高些。
累 啊 !
Lèi ā !
恩 , 要 睡 觉 了, 明 天 上 班, 还 有 一 堆 事 情 要 处 理,加 油 ...
ēn,yào shuì jiào le,míng tiān shàng bān,hái yǒu yī duī shì qíng yāo chǔ lǐ,jiā yóu ... April 10 【转】ADO.NET 的最佳实践技巧 在网上看到这篇文章,不错,有些东西很好,值得好好学习学习,所以,发扬“拿来主义”,把文章拿了过来,以备不时之需(毕竟自己的脑子记不了许多,找起来也麻烦)。
Blog上的这位兄台也是从微软拿来的。【微软原文】
————————————————————————
以下内容需要滚动阅读全文
————————————————————————
简介
本文为您提供了在 Microsoft ADO.NET 应用程序中实现和获得最佳性能、可伸缩性以及功能的最佳解决方案;同时也讲述了使用 ADO.NET 中可用对象的最佳实践;并提出一些有助于优化 ADO.NET 应用程序设计的建议。 本文包含:
使用 DataReader、DataSet、DataAdapter 和 DataViewADO.NET 提供以下两个对象,用于检索关系数据并将其存储在内存中:DataSet 和 DataReader。DataSet 提供一个内存中数据的关系表示形式,一整套包括一些表在内的数据(这些表包含数据、对数据进行排序并约束数据),以及表之间的关系。DataReader 提供一个来自数据库的快速、只进、只读数据流。 当使用 DataSet 时,经常会利用 DataAdapter(也可能是 CommandBuilder)与数据源进行交互。当使用 DataSet 时,也可以利用 DataView 对 DataSet 中的数据应用排序和筛选。也可以从 DataSet 继承,创建强类型 DataSet,用于将表、行和列作为强类型对象属性公开。 下列主题包括的信息涉及:使用 DataSet 或 DataReader 的最佳时机、如何优化访问它们所包含数据、以及如何优化使用 DataAdapter(包括 CommandBuilder)和 DataView 的技巧。 DataSet 与 DataReader 当设计应用程序时,要考虑应用程序所需功能的等级,以确定使用 DataSet 或者是 DataReader。 要通过应用程序执行以下操作,就要使用 DataSet:
对于下列情况,要在应用程序中使用 DataReader:
注填充 DataSet 时,DataAdapter 使用 DataReader。因此,使用 DataAdapter 取代 DataSet 提升的性能表现为节省了 DataSet 占用内存和填充 DataSet 需要的循环。一般来说,此性能提升只是象征性的,因此,设计决策应以所需功能为基础。 使用强类型 DataSet 的好处 DataSet 的另一个好处是可被继承以创建一个强类型 DataSet。强类型 DataSet 的好处包括设计时类型检查,以及 Microsoft Visual Studio .NET 用于强类型 DataSet 语句结束所带来的好处。修改了 DataSet 的架构或关系结构后,就可以创建一个强类型 DataSet,把行和列作为对象的属性公开,而不是作为集合中的项公开。例如,不公开客户表中行的姓名列,而公开 Customer 对象的 Name 属性。类型化 DataSet 从 DataSet 类派生,因此不会牺牲 DataSet 的任何功能。也就是说,类型化 DataSet 仍能远程访问,并作为数据绑定控件(例如 DataGrid)的数据源提供。如果架构事先不可知,仍能受益于通用 DataSet 的功能,但却不能受益于强类型 DataSet 的附加功能。 处理强类型 DataSet 中的空引用 使用强类型 DataSet 时,可以批注 DataSet 的 XML 架构定义语言 (XSD) 架构,以确保强类型 DataSet 正确处理空引用。nullValue 批注使您可用一个指定的值 String.Empty 代替 DBNull、保留空引用或引发异常。选择哪个选项取决于应用程序的上下文。默认情况下,如果遇到空引用,就会引发异常。 有关更多信息,请参阅 Working with a Typed DataSet。 刷新 DataSet 中的数据 如果想用服务器上的更新值刷新 DataSet 中的值,就使用 DataAdapter.Fill。如果有在 DataTable 上定义的主键,DataAdapter.Fill 会根据主键进行新行匹配,并且当更改到现有行时应用服务器上的值。即使刷新之前修改了它们,刷新行的 RowState 仍被设置为 Unchanged。注意,如果没有为 DataTable 定义主键,DataAdapter.Fill 就用可能重复的主键值添加新行。 如果想用来自服务器的当前值刷新表,并同时保留对表中的行所做的任何更改,必须首先用 DataAdapter.Fill 填充表,并填充一个新的 DataTable,然后用 preserveChanges 值 true 把 DataTableMerge 到 DataSet 中。 在 DataSet 中搜索数据 在 DataSet 中查询与特定条件相匹配的行时,可以利用基于索引的查找提高搜索性能。当把 PrimaryKey 值赋给 DataTable 时,会创建一个索引。当给 DataTable 创建 DataView 时,也会创建一个索引。下面是一些利用基于索引进行查找的技巧。
DataView 构造 如果创建了 DataView,并且修改了 Sort、RowFilter 或 RowStateFilter 属性,DataView 就会为基础 DataTable 中的数据建立索引。创建 DataView 对象时,要使用 DataView 构造函数,它用 Sort、RowFilter 和 RowStateFilter 值作为构造函数参数(与基础 DataTable 一起)。结果是创建了一次索引。创建一个“空”DataView 并随后设置 Sort、RowFilter 或 RowStateFilter 属性,会导致索引至少创建两次。 分页 ADO.NET 可以显式控制从数据源中返回什么样的数据,以及在 DataSet 中本地缓存多少数据。对查询结果的分页没有唯一的答案,但下面有一些设计应用程序时应该考虑的技巧。
有关更多信息,请参阅 .NET Data Access Architecture Guide。 用架构填充 DataSet 当用数据填充 DataSet 时,DataAdapter.Fill 方法使用 DataSet 的现有架构,并使用从 SelectCommand 返回的数据填充它。如果在 DataSet 中没有表名与要被填充的表名相匹配,Fill 方法就会创建一个表。默认情况下,Fill 仅定义列和列类型。 通过设置 DataAdapter 的 MissingSchemaAction 属性,可以重写 Fill 的默认行为。例如,要让 Fill 创建一个表架构,并且还包括主键信息、唯一约束、列属性、是否允许为空、最大列长度、只读列和自动增量的列,就要把 DataAdapter.MissingSchemaAction 指定为 MissingSchemaAction.AddWithKey。或者,在调用 DataAdapter.Fill 前,可以调用 DataAdapter.FillSchema 来确保当填充 DataSet 时架构已到位。 对 FillSchema 的调用会产生一个到服务器的额外行程,用于检索附加架构信息。为了获得最佳性能,需要在调用 Fill 之前指定 DataSet 的架构,或者设置 DataAdapter 的 MissingSchemaAction。 使用 CommandBuilder 的最佳实践 假设 SelectCommand 执行单一表 SELECT,CommandBuilder 就会以 DataAdapter 的 SelectCommand 属性为基础自动生成 DataAdapter 的 InsertCommand、UpdateCommand、和 DeleteCommand 属性。下面是为获得最佳性能而使用 CommandBuilder 的一些技巧。
批处理 SQL 语句 很多数据库支持把多条命令合并或批处理成一条单一命令执行。例如,SQL Server 使您可以用分号 (;) 分隔命令。把多条命令合并成单一命令,能减少到服务器的行程数,并提高应用程序的性能。例如,可以把所有预定的删除在应用程序中本地存储起来,然后再发出一条批处理命令调用,从数据源删除它们。 虽然这样做确实能提高性能,但是,当对 DataSet 中的数据更新进行管理时,可能会增加应用程序的复杂性。要保持简单,可能要在 DataSet 中为每个 DataTable 创建一个 DataAdapter。 用多个表填充 DataSet 如果使用批处理 SQL 语句检索多个表并填充 DataSet,第一个表用指定给 Fill 方法的表名命名。后面的表用指定给 Fill 方法的表名加上一个从 1 开始并且增量为 1 的数字命名。例如,如果运行下面的代码: 'Visual Basic
Dim da As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM Customers; SELECT * FROM Orders;", myConnection)
Dim ds As DataSet = New DataSet()
da.Fill(ds, "Customers")
//C#
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Customers; SELECT * FROM Orders;", myConnection);
DataSet ds = new DataSet();
da.Fill(ds, "Customers");
来自 Customers 表的数据放在名为 "Customers" 的 DataTable 中。来自 Orders 表的数据放在名为 "Customers1" 的 DataTable 中。 填充完 DataSet 之后,可以很容易地把 "Customers1" 表的 TableName 属性改为 "Orders"。但是,后面的填充会导致 "Customers" 表被重新填充,而 "Orders" 表会被忽略,并创建另外一个 "Customers1" 表。为了对这种情况作出补救,创建一个 DataTableMapping,把 "Customers1" 映射到 "Orders",并为其他后面的表创建其他的表映射。例如: 'Visual Basic
Dim da As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM Customers; SELECT * FROM Orders;", myConnection)
da.TableMappings.Add("Customers1", "Orders")
Dim ds As DataSet = New DataSet()
da.Fill(ds, "Customers")
//C#
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Customers; SELECT * FROM Orders;", myConnection);
da.TableMappings.Add("Customers1", "Orders");
DataSet ds = new DataSet();
da.Fill(ds, "Customers");
使用 DataReader 下面是一些使用 DataReader 获得最佳性能的技巧,同时还回答了一些关于使用 DataReader 的常见问题。
二进制大对象 (BLOB) 用 DataReader 检索二进制大对象 (BLOB) 时,应该把 CommandBehavior.SequentialAccess 传递给 ExecuteReader 方法调用。因为 DataReader 的默认行为是每次 Read 都把整行加载到内存,又因为 BLOB 值可能非常大,所以结果可能由于单个 BLOB 而使大量内存被用光。SequentialAccess 将 DataReader 的行为设置为只加载请求的数据。然后还可以使用 GetBytes 或 GetChars 控制每次加载多少数据。 记住,使用 SequentialAccess 时,不能不按顺序访问 DataReader 返回的不同字段。也就是说,如果查询返回三列,其中第三列是 BLOB,并且想访问前两列中的数据,就必须在访问 BLOB 数据之前先访问第一列的值,然后访问第二列的值。这是因为现在数据是顺序返回的,并且 DataReader 一旦读过该数据,该数据就不再可用。 有关如何在 ADO.NET 中访问 BLOB 的详细描述,请参阅 Obtaining BLOB Values from a Database。 使用命令ADO.NET 提供了几种命令执行的不同方法以及优化命令执行的不同选项。下面包括一些技巧,它们是关于选择最佳命令执行以及如何提高执行命令的性能。 使用 OleDbCommand 的最佳实践 不同 .NET 框架数据提供程序之间的命令执行被尽可能标准化了。但是,数据提供程序之间仍然存在差异。下面给出一些技巧,可微调用于 OLE DB 的 .NET 框架数据提供程序的命令执行。
使用 SqlCommand 的最佳实践 使用 SqlCommand 执行存储过程的快速提示:如果调用存储过程,将 SqlCommand 的 CommandType 属性指定为 StoredProcedure 的 CommandType。这样通过将该命令显式标识为存储过程,就不需要在执行之前分析命令。 使用 Prepare 方法 对于重复作用于数据源的参数化命令,Command.Prepare 方法能提高性能。Prepare 指示数据源为多次调用优化指定的命令。要想有效利用 Prepare,需要彻底理解数据源是如何响应 Prepare 调用的。对于一些数据源(例如 SQL Server 2000),命令是隐式优化的,不必调用 Prepare。对于其他(例如 SQL Server 7.0)数据源,Prepare 会比较有效。 显式指定架构和元数据 只要用户没有指定元数据信息,ADO.NET 的许多对象就会推断元数据信息。下面是一些示例:
但是,每次用到这些特性,都会有性能损失。建议将这些特性主要用于设计时和即席应用程序中。在可能的情况下,显式指定架构和元数据。其中包括在 DataSet 中定义表和列、定义 DataAdapter 的 Command 属性、以及为 Command 定义 Parameter 信息。 ExecuteScalar 和 ExecuteNonQuery 如果想返回像 Count(*)、Sum(Price) 或 Avg(Quantity) 的结果那样的单值,可以使用 Command.ExecuteScalar。ExecuteScalar 返回第一行第一列的值,将结果集作为标量值返回。因为单独一步就能完成,所以 ExecuteScalar 不仅简化了代码,还提高了性能;要是使用 DataReader 就需要两步才能完成(即,ExecuteReader + 取值)。 使用不返回行的 SQL 语句时,例如修改数据(例如INSERT、UPDATE 或 DELETE)或仅返回输出参数或返回值,请使用 ExecuteNonQuery。这避免了用于创建空 DataReader 的任何不必要处理。 有关更多信息,请参阅 Executing a Command。 测试 Null 如果表(在数据库中)中的列允许为空,就不能测试参数值是否“等于”空。相反,需要写一个 WHERE 子句,测试列和参数是否都为空。下面的 SQL 语句返回一些行,它们的 LastName 列等于赋给 @LastName 参数的值,或者 LastName 列和 @LastName 参数都为空。 SELECT * FROM Customers WHERE ((LastName = @LastName) OR (LastName IS NULL AND @LastName IS NULL)) 把 Null 作为参数值传递 对数据库的命令中,当把空值作为参数值发送时,不能使用 null(Visual Basic庐 .NET 中为 Nothing)。而需要使用 DBNull.Value。例如: 'Visual Basic
Dim param As SqlParameter = New SqlParameter("@Name", SqlDbType.NVarChar, 20)
param.Value = DBNull.Value
//C#
SqlParameter param = new SqlParameter("@Name", SqlDbType.NVarChar, 20);
param.Value = DBNull.Value;
执行事务 ADO.NET 的事务模型已经更改。在 ADO 中,当调用 StartTransaction 时,调用之后的任何更新操作都被视为是事务的一部分。但是,在 ADO.NET 中,当调用 Connection.BeginTransaction 时,会返回一个 Transaction 对象,需要把它与 Command 的 Transaction 属性联系起来。这种设计可以在一个单一连接上执行多个根事务。如果未将 Command.Transaction 属性设置为一个针对相关的 Connection 而启动的 Transaction,那么 Command 就会失败并引发异常。 即将发布的 .NET 框架将使您可以在现有的分布式事务中手动登记。这对于对象池方案来说很理想;在该方案中,一个池对象打开一次连接,但是在多个独立的事务中都涉及到该对象。.NET 框架 1.0 发行版中这一功能并不可用。 有关事务的更多信息,请参阅 Performing Transactions 以及 .NET Data Access Architecture Guide。 使用连接高性能应用程序与使用中的数据源保持最短时间的连接,并且利用性能增强技术,例如连接池。下面的主题提供一些技巧,有助于在使用 ADO.NET 连接到数据源时获得更好的性能。 连接池 用于 ODBC 的 SQL Server、OLE DB 和 .NET 框架数据提供程序隐式缓冲连接。通过在连接字符串中指定不同的属性值,可以控制连接池的行为。有关如何控制连接池的行为的详细信息,请参阅 Connection Pooling for the SQL Server .NET Data Provider 和 Connection Pooling for the OLE DB .NET Data Provider。 用 DataAdapter 优化连接 DataAdapter 的 Fill 和 Update 方法在连接关闭的情况下自动打开为相关命令属性指定的连接。如果 Fill 或 Update 方法打开了连接,Fill 或 Update 将在操作完成的时候关闭它。为了获得最佳性能,仅在需要时将与数据库的连接保持为打开。同时,减少打开和关闭多操作连接的次数。 如果只执行单个的 Fill 或 Update 方法调用,建议允许 Fill 或 Update 方法隐式打开和关闭连接。如果对 Fill 和/或 Update 调用有很多,建议显式打开连接,调用 Fill 和/或 Update,然后显式关闭连接。 另外,当执行事务时,显式地在开始事务之前打开连接,并在提交之后关闭连接。例如: 'Visual Basic
Public Sub RunSqlTransaction(da As SqlDataAdapter, myConnection As SqlConnection, ds As DataSet)
myConnection.Open()
Dim myTrans As SqlTransaction = myConnection.BeginTransaction()
myCommand.Transaction = myTrans
Try
da.Update(ds)
myTrans.Commit()
Console.WriteLine("Update successful.")
Catch e As Exception
Try
myTrans.Rollback()
Catch ex As SqlException
If Not myTrans.Connection Is Nothing Then
Console.WriteLine("An exception of type " & ex.GetType().ToString() & _
" was encountered while attempting to roll back the transaction.")
End If
End Try
Console.WriteLine("An exception of type " & e.GetType().ToString() & " was encountered.")
Console.WriteLine("Update failed.")
End Try
myConnection.Close()
End Sub
//C#
public void RunSqlTransaction(SqlDataAdapter da, SqlConnection myConnection, DataSet ds)
{
myConnection.Open();
SqlTransaction myTrans = myConnection.BeginTransaction();
myCommand.Transaction = myTrans;
try
{
da.Update(ds);
myCommand.Transaction.Commit();
Console.WriteLine("Update successful.");
}
catch(Exception e)
{
try
{
myTrans.Rollback();
}
catch (SqlException ex)
{
if (myTrans.Connection != null)
{
Console.WriteLine("An exception of type " + ex.GetType() +
" was encountered while attempting to roll back the transaction.");
}
}
Console.WriteLine(e.ToString());
Console.WriteLine("Update failed.");
}
myConnection.Close();
}
始终关闭 Connection 和 DataReader 完成对 Connection 或 DataReader 对象的使用后,总是显式地关闭它们。尽管垃圾回收最终会清除对象并因此释放连接和其他托管资源,但垃圾回收仅在需要时执行。因此,确保任何宝贵的资源被显式释放仍然是您的责任。并且,没有显式关闭的 Connections 可能不会返回到池中。例如,一个超出作用范围却没有显式关闭的连接,只有当池大小达到最大并且连接仍然有效时,才会被返回到连接池中。 注 不要在类的 Finalize 方法中对 Connection、DataReader 或任何其他托管对象调用 Close 或 Dispose。最后完成的时候,仅释放类自己直接拥有的非托管资源。如果类没有任何非托管资源,就不要在类定义中包含 Finalize 方法。 在 C# 中使用 "Using" 语句 对于 C# 程序员来说,确保始终关闭 Connection 和 DataReader 对象的一个方便的方法就是使用 using 语句。using 语句在离开自己的作用范围时,会自动调用被“使用”的对象的 Dispose。例如: //C#
string connString = "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;";
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT CustomerId, CompanyName FROM Customers";
conn.Open();
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
Console.WriteLine("{0}\t{1}", dr.GetString(0), dr.GetString(1));
}
}
Using 语句不能用于 Microsoft庐 Visual Basic庐 .NET。 避免访问 OleDbConnection.State 属性 如果连接已经打开,OleDbConnection.State 属性会对 DBPROP_CONNECTIONSTATUS 属性的 DATASOURCEINFO 属性集执行本地 OLE DB 调用 IDBProperties.GetProperties,这可能会导致对数据源的往返行程。也就是说,检查 State 属性的代价可能很高。所以仅在需要时检查 State 属性。如果需要经常检查该属性,监听 OleDbConnection 的 StateChange 事件可能会使应用程序的性能好一些。有关 StateChange 事件的详细信息,请参阅 Working with Connection Events。 与 XML 集成ADO.NET 在 DataSet 中提供了广泛的 XML 集成,并公开了 SQL Server 2000 及其更高版本提供的部分 XML 功能。还可以使用 SQLXML 3.0 广泛地访问 SQL Server 2000 及其更高版本中的 XML 功能。下面是使用 XML 和 ADO.NET 的技巧和信息。 DataSet 和 XML DataSet 与 XML 紧密集成,并提供如下功能:
注 可以使用这种同步把 XML 功能(例如,XPath 查询和 XSLT 转换)应用到 DataSet 中的数据,或者在保留原始 XML 保真度的前提下为 XML 文档中数据的全部或其中一个子集提供关系视图。 关于 DataSet 提供的 XML 功能的详细信息,请参阅 XML and the DataSet。 架构推断 从 XML 文件加载 DataSet 时,可以从 XSD 架构加载 DataSet 架构,或者在加载数据前预定义表和列。如果没有可用的 XSD 架构,而且不知道为 XML 文件的内容定义哪些表和列,就可以在 XML 文档结构的基础上对架构进行推断。 架构推断作为迁移工具很有用,但应只限于设计阶段应用程序,这是由于推断处理有如下限制。
有关更多信息,请参阅 Inferring DataSet Relational Structure from XML。 用于 XML 查询的 SQL Server 如果正从 SQL Server 2000 FOR XML 返回查询结果,可以让用于 SQL Server 的 .NET 框架数据提供程序使用 SqlCommand.ExecuteXmlReader 方法直接创建一个 XmlReader。 SQLXML 托管类 .NET 框架中有一些类,公开用于 SQL Server 2000 的 XML 的功能。这些类可在 Microsoft.Data.SqlXml 命名空间中找到,它们添加了执行 XPath 查询和 XML 模板文件以及把 XSLT 转换应用到数据的能力。 SQLXML 托管类包含在用于 Microsoft SQL Server 2000 的 XML (SQLXML 2.0) 发行版中,可从 XML for Microsoft SQL Server 2000 Web Release 2 (SQLXML 2.0) 获得。 更多有用的技巧下面是一些编写 ADO.NET 代码时的通用技巧。 避免自动增量值冲突 就像大多数数据源一样,DataSet 使您可标识那些添加新行时自动对其值进行递增的列。在 DataSet 中使用自动增量的列时,如果自动增量的列来自数据源,可避免添加到 DataSet 的行和添加到数据源的行之间本地编号冲突。 例如,考虑一个表,它的主键列 CustomerID 是自动增量的。两个新的客户信息行添加到表中,并接收到自动增量的 CustomerID 值 1 和 2。然后,只有第二个客户行被传递给 DataAdapter 的方法 Update,新添加的行在数据源接收到一个自动增量的 CustomerID 值 1,与 DataSet 中的值 2 不匹配。当 DataAdapter 用返回值填充表中第二行时,就会出现约束冲突,因为第一个客户行已经使用了 CustomerID 值 1。 要避免这种情况,建议在使用数据源上自动增量的列以及 DataSet 上自动增量的列时,把 DataSet 中的列创建为 AutoIncrementStep 值等于 -1 并且 AutoIncrementSeed 值等于 0,另外,还要确保数据源生成的自动增量标识值从 1 开始,并且以正阶值递增。因此,DataSet 为自动增量值生成负数,与数据源生成的正自动增量值不冲突。另外一个选择是使用 Guid 类型的列,而不是自动增量的列。生成 Guid 值的算法应该永远不会使数据源中生成的 Guid 值与 DataSet 中生成的 Guid 值一样。 如果自动增量的列只是用作唯一值,而且没有任何意义,就考虑使用 Guid 代替自动增量的列。它们是唯一的,并且避免了使用自动增量的列所必需的额外工作。 有关从数据源检索自动增量的列值的示例,请参阅 Retrieving Identity or AutoNumber Values。 检查开放式并发冲突 按照设计,由于 DataSet 是与数据源断开的,所以,当多个客户端在数据源上按照开放式并发模型更新数据时,需要确保应用程序避免冲突。 在测试开放式并发冲突时有几项技术。一项技术涉及在表中包含时间戳列。另外一项技术是,验证一行中所有列的原始值是否仍然与通过在 SQL 语句中使用 WHERE 子句进行测试时在数据库中找到的值相匹配。 有关包含代码示例的该主题的详细讨论,请参阅 Optimistic Concurrency。 多线程编程 ADO.NET 对性能、吞吐量和可伸缩性进行优化。因此,ADO.NET 对象不锁定资源,并且必须只用于单线程。一个例外是 DataSet,它对多个阅读器是线程安全的。但是,在写的时候需要把 DataSet 锁定。 仅在需要的时候才用 COM Interop 访问 ADO ADO.NET 的设计目的是成为许多应用程序的最佳解决方案。但是,有些应用程序需要只有使用 ADO 对象才有的功能,例如,ADO 多维 (ADOMD)。在这些情况下,应用程序可以用 COM Interop 访问 ADO。注意使用 COM Interop 访问具有 ADO 的数据会导致性能降低。在设计应用程序时,首先在实现用 COM Interop 访问 ADO 的设计之前,先确定 ADO.NET 是否满足设计需求。 March 28 常用术语
February 28 IEWebBrowser以下是引用:
我对IEWebBrowser这个组件的execWB方法整理了一下﹐希望对大家有所帮助。
1. <object id="WebBrowser" width=0 height=0 classid="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"></object> 2. 调用方法。 WebBrowser.ExecWB nCmdID, nCmdExecOpt, [pvaIn], [pvaOut] 3. 参数说明。 (a).nCmdID OLECMDID_OPEN = 1, OLECMDID_NEW = 2, OLECMDID_SAVE = 3, OLECMDID_SAVEAS = 4, OLECMDID_SAVECOPYAS = 5, OLECMDID_PRINT = 6, OLECMDID_PRINTPREVIEW = 7, OLECMDID_PAGESETUP = 8, OLECMDID_SPELL = 9, OLECMDID_PROPERTIES = 10, OLECMDID_CUT = 11, OLECMDID_COPY = 12, OLECMDID_PASTE = 13, OLECMDID_PASTESPECIAL = 14, OLECMDID_UNDO = 15, OLECMDID_REDO = 16, OLECMDID_SELECTALL = 17, OLECMDID_CLEARSELECTION = 18, OLECMDID_ZOOM = 19, OLECMDID_GETZOOMRANGE = 20 OLECMDID_UPDATECOMMANDS = 21 OLECMDID_REFRESH = 22 OLECMDID_STOP = 23 OLECMDID_HIDETOOLBARS = 24 OLECMDID_SETPROGRESSMAX = 25 OLECMDID_SETPROGRESSPOS = 26 OLECMDID_SETPROGRESSTEXT = 27 OLECMDID_SETTITLE = 28 OLECMDID_SETDOWNLOADSTATE = 29 OLECMDID_STOPDOWNLOAD = 30 上面的关键词都可以在浏览器的菜单里面找到对应的选项﹐大家一看就明白的﹗ (b).nCmdExecOpt OLECMDEXECOPT_DODEFAULT = 0, OLECMDEXECOPT_PROMPTUSER = 1, LECMDEXECOPT_DONTPROMPTUSER = 2, OLECMDEXECOPT_SHOWHELP = 3 对于这个参数﹐一般来说﹐选1就可以了。 这是调用IE的”另存为”功能的示例﹕ <object id="WebBrowser" width=0 height=0 classid="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"></object> <A href="javascript:WebBrowser.ExecWB(4,1);">Save-存储 from:http://www.6to23.com/s11/s11d5/20031222114741.htm
January 09 DataGrid 资料关于datagrid的打印 DataGrid Web控件深度历险(3) part2 DataGrid Web控件深度历险(3) part3 datagrid分页问题(前后跳页)《控件版》 DataGrid Web控件深度历险(2) Part1 DataGrid Web控件深度历险(1) 如何在DataGrid里面产生滚动条而不滚动题头 使用在.net 框架上的DataGrid數據分頁控件 DataGrid连接Access的快速分页法(5)——实现快速分页 DataGrid连接Access的快速分页法(4)——动态生成SQL语句 DataGrid连接Access的快速分页法(3)——SQL语句的选用(降序) DataGrid连接Access的快速分页法(2)——SQL语句的选用(升序) DataGrid连接Access的快速分页法(1)——需求与现状 常见 Datagrid 错误(other) XP 风格的可拖动列、可排序、可改变宽度的DataGrid的例子 利用radio实现Datagrid的单选 重画系列:DataGridColumnStyle之测试代码 将OleDbDataAdapter绑定到Winform下的DataGrid 去除Asp:DataGrid中无用ViewState的方法(2) 去除Asp:DataGrid中无用ViewState的方法(1) 将DBF,XLS,XML,MDB文件导入C#DataGrid的方法 动态创建DataGrid的模版列 DataTable中数据记录的统计 (ASP.NET)用动态属性和DataView实现DataGrid的双向排序 如何同步滚动两个相同的DataGrid asp.net中DataGrid性能测试 让Asp.NET的DataGrid可排序、可选择、可分页 DataGrid传统分页方式 在后代码里创建DataGrid控件 ASP.net中的Datagrid自定义分页功能 在Pocket PC应用程序中使用DataGrid控件 创建可拖动列的DataGrid(2) 创建可拖动列的DataGrid DataGrid和CheckBox的混合使用 利用Session纪录datagrid模板列中CheckBox的状态 DataGrid模板列中TextBox的焦点相应键盘事件 给DataGrid添加确定删除的功能 如何给DataGrid添加自动增长列 如何利用RadioButtonList实现datagrid列的单选 ASP.Net WebMatrix中Datagrid使用模板列对数据显示进行排版 格式化 DataGrid 输出 如何实现单击在DATALIST(DATAGRID)的HEADER加入的CHECKBOX,进行DATALIST(DATAGRID)中的CHECKBOX列全选或全不选 向datagrid中加横向 纵向的合计 (在datatable中实现,datatable间倒数据) 基于ADO+Adodc控件+DataGrid控件制作的一个数据库编辑程序(完整原程序) 如何实现自定义及自动逐页打印DataGrid显示的内容 合并datagrid中内容相同的单元格 创建固定表头、表格体滚动的DataGrid 创建跨多列、多行表头的DataGrid 在DataGrid中添加一个合计字段 为DataGrid添加自动编号功能 格式化DataGrid的例子【将数据源中的0,1值转换成实际的文字】 Henry手记—Web Form中的Datagrid的自定义分页 DataGrid控件通用打印类 为DataGrid添加CheckBox控件 VB.NET中关于DataGrid颜色的自定义 在DataGrid快速添加新行 Henry手记-Datagrid事件响应(二) datagrid技巧之一:代码控制选中行的颜色 在C#里实现DATAGRID的打印预览和打印 Binding a DataGrid to an ADO Recordset Creating DataGrid Templated Columns Dynamically - Part I DataTable,DataView和DataGrid中一些容易混淆的概念 动态的管理ASP.NET DataGrid数据列 Henry手记-Datagrid键盘事件响应(二) Henry手记—从Datagrid的标题居中说起 用嵌套的DataGrid实现主从式表的显示 DataGrid中嵌套使用Repeater Henry手记 - Datagrid键盘事件响应(一) 给datagrid控件建立稳固的双向排序(asp.net) asp.net笔记(dataset,datagrid) DataSet导出CSV格式(ASP.NET,C#) Henry手记:Datagrid事件响应 Henry手记:WinForm Datagrid结构剖析(三)使用代码 Henry手记:WinForm Datagrid结构剖析(三)类代码 Henry手记:WinForm Datagrid结构剖析(三) ADO在vb.net中的使用(与datagrid结合) Henry手记:WinForm Datagrid结构剖析(二)程序 Henry手记:WinForm Datagrid结构剖析(二) ASP.NET中的DataGrid的属性 EnableViewState="false"的DataGrid分页 Datagrid 链接数据库Access DataGrid 链接Access数据库 Henry手记:WinForm Datagrid结构剖析(一) 把Excel文件中的数据读入到DataGrid中 如何创建一个用弹出窗口来查看详细信息的超链接列 DataGrid使用技巧(四) DataGrid使用技巧(三) DataGrid使用技巧(二) DataGrid使用技巧(一) 神奇的 DataGrid 使用c#+(datagrid控件)编辑xml文件 在DataGrid中创建一个弹出式Details窗口 在DataGrid中创建一个弹出式Details窗口 vs.net beta 2中利用DataGrid分页详解 使用 ASP+ DataGrid 控件来创建主视图/详细资料视图 (2) 使用 ASP+ DataGrid 控件来创建主视图/详细资料视图 October 03 去除同一表中的两条相同记录去除重复值
1.如果有ID字段,就是具有唯一性的字段 delect table where id not in ( select max(id) from table group by col1,col2,col3...)
group by 子句后跟的字段就是你用来判断重复的条件,如只有col1,那么只要col1字段内容相同即表示记录相同。 2,如果是判断所有字段也可以这样
select * into #aa from table group by id1,id2,.... delete table insert into table select * from #aa 3,没有ID的情况
select identity(int,1,1) as id,* into #temp from tabel
delect # where id not in ( select max(id) from # group by col1,col2,col3...) delect table inset into table(...) select ..... from #temp col1+','+col2+','...col5 联合主键 select * from table where col1+','+col2+','...col5 in ( select max(col1+','+col2+','...col5) from table
where having count(*)>1 group by col1,col2,col3,col4 ) group by 子句后跟的字段就是你用来判断重复的条件,如只有col1,那么只要col1字段内容相同即表示记录相同。 2,
select identity(int,1,1) as id,* into #temp from tabel select * from #temp where id in ( select max(id) from #emp where having count(*)>1 group by col1,col2,col3...) From:csdn--> txlicenhe(马可) 删除重复的,只留一条:
alter table 表 add newfield int identity(1,1)
delete 表
where newfield not in( select min(newfield) from 表 group by 除newfield外的所有字段 ) alter table 表 drop column newfield
或: select distinct * into #temp from 表
truncate table 表 insert 表 select * from #temp drop table #temp From:csdn-->pengdali(大力 V3.0) 先在你的表中增加一个标识字段.
再删除记录.
然后删除标识字段就行了.
From:csdn--> zjcxc(邹建) 在这次的问题中我用delect table where id not in ( select max(id) from table group by col1,col2,col3...) 解决了问题 ASP的游标浅谈ASP的游标选择(Recordset Cursors) 在ADO里创建一个recordset对象有以下两种方法: Set rs = Server.CreateObject("ADODB.Recordset") Dim rs, conn Set conn = Server.CreateObject("ADODB.Connection") conn.open "DSN=student;UID=;PWD=" Application("Connection_String") Set rs = conn.Execute("SELECT * FROM score") 当我们拥有了recordset对象后就可以用rs来引用它. 如果这个recordset对象由ADO/ASP隐式地创建的,它的游标类型是forward-only. 然而,当你显式地创建了一个recordset对象,你就能用如下的代码来设置你所想使用的游标类型: 游标类型可以是以下四种类型之一: Static Keyset Dynamic Forward-only型游标占用最少的资源,因而能得到最高的性能. 它也是recordset缺省的游标类型,唯一的缺点是只能单向移动游标. 你只能从头到尾单向遍历记录集,亦即只能使用MoveNext这样的方法,而不能使用MovePrev. 比方说,如果你企图在一个forward-only的recordset里使用MovePrev的方法,你将得到一个错误提示.要使用一个forward-only型的游标,你应该键入: 注意: 在你的每一个ASP页面中一定要包含adovbs.inc这个文件. Dynamic和Keyset型游标可以实时查看数据的更动. 但这只是在VisualBASIC应用程序起作用,对于Web页面则一点儿用都没有. 一旦用户发出数据请求,就同static型游标一样数据集中得到那一时刻的数据映像. 如果用户不刷新他们的浏览器页面,想持续地反应数据的变化是不可能的. 由于Web浏览方式的特殊性,你可能根本用不到Keyset或Dynamic型的游标,它们特别耗费系统的资源. 如果你需要各方向遍历你的数据集,或是想得知数据集中的记录数,就采用Static型游标,否则就用Forward-only型的. 总之,你在创建recordset时,应该选择合适的游标! from:http://www.hermes.com.cn/pagemake/2000.05.18.htm other:
set rs=conn.execute(sql) 可以返回记录集 conn.execute对大量数据操作时速度快 RS对大量数据操作时速度慢 September 30 禁用浏览器后退之方法比较禁用浏览器后退之方法比较<转>
浏览器的后退按钮使得我们能够方便地返回以前访问过的页面,它无疑非常有用。但有时候我们不得不关闭这个功能,以防止用户打乱预定的页面访问次序。本文介绍网络上可找到的各种禁用浏览器后退按钮方案,分析它们各自的优缺点和适用场合。 一、概述
曾经有许多人问起,“怎样才能‘禁用’浏览器的后退按钮?”,或者“怎样才能防止用户点击后退按钮返回以前浏览过的页面?”在ASP论坛上,这个问题也是问得最多的问题之一。遗憾的是,答案非常简单:我们无法禁用浏览器的后退按钮。 起先我对于居然有人想要禁用浏览器的后退按钮感到不可思议。后来,看到竟然有那么多的人想要禁用这个后退按钮,我也就释然(想要禁用的只有后退按钮,不包括浏览器的前进按钮)。因为在默认情况下,用户提交表单之后可以通过后退按钮返回表单页面(而不是使用“编辑”按钮!),然后再次编辑并提交表单向数据库插入新的记录。这是我们不愿看到的。
因此我就决定要找出避免出现这种情况的方法。我访问了许多网站,参考了这些网站所介绍的各种实现方法。如果你经常访问ASP编程网站,本文所介绍的部分内容你可能已经见到过。本文的任务是把各种可能的方法都介绍给大家,然后找出最好的方法!
二、禁止缓存
在我找到的许多方案中,其中有一种建议禁止页面缓存。具体是使用服务器端脚本,如下所示:
< %
Response.Buffer = True
Response.ExpiresAbsolute = Now() - 1
Response.Expires = 0
Response.CacheControl = "no-cache"
% >
这种方法非常有效!它强制浏览器重新访问服务器下载页面,而不是从缓存读取页面。使用这种方法时,编程者的主要任务是创建一个会话级的变量,通过这个变量确定用户是否仍旧可以查看那个不适合通过后退按钮访问的页面。由于浏览器不再缓存这个页面,当用户点击后退按钮时浏览器将重新下载该页面,此时程序就可以检查那个会话变量,看看是否应该允许用户打开这个页面。
例如,假设我们有如下表单:
< %
Response.Buffer = True
Response.ExpiresAbsolute = Now() - 1
Response.Expires = 0
Response.CacheControl = "no-cache"
If Len(Session("FirstTimeToPage")) > 0 then &single; 用户已经访问过当前页面,现在是再次返回访问。
&single; 清除会话变量,将用户重定向到登录页面。
Session("FirstTimeToPage") = ""
Response.Redirect "/Bar.asp"
Response.End
End If
&single; 如果程序运行到这里,说明用户能够查看当前页面 &single; 以下开始创建表单
%>
< form method=post action="SomePage.asp">
< input type=submit>
< /form>
我们借助会话变量FirstTimeToPage检查用户是否是第一次访问当前页面。如果不是第一次(即Session("FirstTimeToPage")包含某个值),那么我们就清除会话变量的值,然后把用户重新定向到一个开始页面。这样,当表单提交时(此时SompePage.asp被打开),我们必须赋予FirstTimeToPage一个值。即,在SomePage.asp中我们需要加上下面的代码:
Session("FirstTimeToPage") = "NO"
这样,已经打开SomePage.asp的用户如果点击后退按钮,浏览器将重新请求服务器下载页面,服务器检查到Session("FirstTimeToPage")包含了一个值,于是就清除Session("FirstTimeToPage"),并把用户重定向到其他页面。当然,所有这一切都需要用户启用了Cookie,否则会话变量将是无效的。(有关该问题的更多说明,请参见For session variables to work, must the Web visitor have cookies enabled?)
另外,我们也可以用客户端代码使浏览器不再缓存Web页面:
< html>
< head>
< meta http-equiv="Expires" CONTENT="0">
< meta http-equiv="Cache-Control" CONTENT="no-cache">
< meta http-equiv="Pragma" CONTENT="no-cache">
< /head>
如果使用上面的方法强制浏览器不再缓存Web页面,必须注意以下几点:
只有在使用安全连接时“Pragma: no-cache”才防止浏览器缓存页面。对于不受安全保护的页面,“Pragma: no-cache”被视为与“Expires: -1”相同,此时浏览器仍旧缓存页面,但把页面标记为立即过期。
在IE 4或5中,“Cache-Control”META HTTP-EQUIV标记将被忽略,不起作用。 在实际应用中我们可以加上所有这些代码。然而,由于这种方法不能适用于所有的浏览器,所以是不推荐使用的。但如果是在Intranet环境下,管理员可以控制用户使用哪种浏览器,我想还是有人会使用这种方法。 三、其他方法
接下来我们要讨论的方法以后退按钮本身为中心,而不是浏览器缓存。这儿有一篇文章Rewiring the Back Button很值得参考。不过我注意到,如果使用这种方法,虽然用户点击一下后退按钮时他不会看到以前输入数据的页面,但只要点击两次就可以,这可不是我们希望的效果,因为很多时候,固执的用户总是能够找到绕过预防措施的办法。
另外一种禁用后退按钮的办法是用客户端JavaScript打开一个没有工具条的窗口,这使得用户很难返回前一页面,但不是不可能。一种更安全但相当恼人的方法是,当表单提交时打开一个新的窗口,与此同时关闭表单所在的窗口。但我觉得这种方法不值得认真考虑,因为我们总不能让用户每提交一个表单就打开一个新窗口。
那么,在那个我们不想让用户返回的页面是否也可以加入JavaScript代码呢?在这个页面中加入的JavaScript代码可用来产生点击前进按钮的效果,这样也就抵消了用户点击后退按钮所产生的动作。用于实现该功能的JavaScript代码如下所示:
< script language="JavaScript"> < !--
javascript:window.history.forward(1);
//-->
< /script>
同样地,这种方法虽然有效,但距离“最好的方法”还差得很远。后来我又看到有人建议用location.replace从一个页面转到另一个页面。这种方法的原理是,用新页面的URL替换当前的历史纪录,这样浏览历史记录中就只有一个页面,后退按钮永远不会变为可用。我想这可能正是许多人所寻求的方法,但这种方法仍旧不是任何情况下的最好方法。使用这种方法的实例如下所示:
< A HREF="PageName.htm" onclick="javascript:location.replace(this.href);
event.returnValue=false; ">
禁止后退到本页面的链接< /A>
试试下面这个链接:
禁止后退到本页面的链接!
这种方法的缺点在于:简单地运用Response.Redirect将不再有效,这是因为每次用户从一个页面转到另一个页面,我们都必须用客户端代码清除location.history。另外还要注意,这种方法清除的是最后一个访问历史记录,而不是全部的访问记录。
点击上面的链接,你将打开一个简单的HTML页面。再点击后退按钮,你可以看到这时打开的不是本页面,而是本页面之前的页面!(当然,你必须在浏览器中启用了客户端JavaScript代码。)
经过一番仔细的寻寻觅觅之后,我发现仍旧无法找出真正能够完全禁用浏览器后退按钮的办法。所有这
META 标签META 标签,是 HTML 语言 head 区的一个辅助性标签。在几乎所有的网页里,我们都可以看到类似下面这段 html 代码: [转载] ASCII码对照表
August 23 正则表达式1用正则表达式搜索电子邮件
<!--
蛙蛙推荐:用正则表达式搜索电子邮件 提出问题:给定一个字符串,从中找出5个电子邮件,把其中的电子邮件用红色着重表示出来(或者是其它能着重显示的方式), 并且把这5个邮件保存成一个用逗号分割开的字符串,并打印出来. --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> New Document </TITLE> <META NAME="Generator" CONTENT="EditPlus"> <META NAME="Author" CONTENT="蛙蛙王子"> <META NAME="Keywords" CONTENT="蛙蛙池塘"> <META NAME="Description" CONTENT="呱呱"> <SCRIPT LANGUAGE="JScript"> function wawa_matchmail(str) { /* *--------------- wawa_matchmail(str) ----------------- * wawa_matchmail(str) * 功能:搜索一个字符串内符合邮件格式的子串,返回一个新串,包含5个搜索出来的邮件,并用逗号隔开. * 参数:str,字符串类型,要搜索的主串. * 实例:wawa_matchmail("only@sohu.com,ddd,only163.com") * author:天极.蛙蛙王子 * update:2004-7-28 13:07 *--------------- wawa_matchmail(str) ----------------- */ //我这里用的是string对象的match方法实现的. var re= /\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+/g; var m=MainString.match(re); var m1="" for(var i=0;i<m.length&&i<5;i++){ m1+=m[i].fontcolor("blue")+","; } return (m1); } function wawa_replacemail(str) { /* *--------------- wawa_replacemail(str) ----------------- * wawa_replacemail(str) * 功能:搜索一个字符串内符合邮件格式的子串,生成一个新串,并用红色来表示邮件部分. * 参数:str,字符串类型,要搜索的主串. * 实例:wawa_replacemail("only@sohu.com,ddd,only163.com") * author:天极.蛙蛙王子 * update:2004-7-28 13:07 *--------------- wawa_replacemail(str) ----------------- */ //这里用的是政则表达式对象和RegExp来实现的. var s=''; //var re = new RegExp("d(b+)(d)","ig"); var re= /\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+/g; var j=0; while((arr = re.exec(str))!=null) { s += str.substring(j,(RegExp.lastIndex-RegExp.lastMatch.length)); s += RegExp.lastMatch.fontcolor("red"); j=RegExp.lastIndex //为了让大家熟悉正则表达式对象和RegExp对象的属性,我把它们都列了出来,如果你想学习它的用法,把注释去掉就可以看到很明显的输出了 //s += "=======================================<br>"; //s += "$1 returns: " + RegExp.$1 + "<br>"; //s += "$2 returns: " + RegExp.$2 + "<br>"; //s += "$3 returns: " + RegExp.$3 + "<br>"; //s += "input returns : " + RegExp.input + "<br>"; //s += "index returns : " + RegExp.index + "<br>"; //s += "lastIndex returns : " + RegExp.lastIndex + "<br>"; //s += "lastMatch returns: " + RegExp.lastMatch + "<br>"; //s += "leftContext returns: " + RegExp.leftContext + "<br>"; //s += "rightContext returns: " + RegExp.rightContext + "<br>"; //s += "lastParen returns: " + RegExp.lastParen + "<br>"; //s += "arr.index returns: " + arr.index + "<br>"; //s += "arr.lastIndex returns: " + arr.lastIndex + "<br>"; //s += "arr.input returns: " + arr.input + "<br>"; //s += "re.lastIndex returns: " + re.lastIndex + "<br>"; //s += "re.source returns: " + re.source + "<br>"; //s += "=======================================<br>"; } s += RegExp.rightContext; return(s); //Return results. } </SCRIPT> </HEAD> <BODY> <script> //下面定义主串 var MainString="蛙蛙王子,onlytiancai@sohu.com ,33@@@,三等分,guagua@wawa.cn"; MainString+="only@only.com,,,,ad,一二三四<a>abcd@abcd.com@abc</a>sdfsdf feiyang@163.com"; MainString+="sdf呱呱sfd@msn.com.dsfsdf__#co,我是一颗秋天的树zhang@yushang.com.完了,哈哈"; //下面打印主串 document.write("原字符串:".bold()+"<br>"+MainString); //下面打印搜索出来的5个邮件 document.write("<BR><BR>搜索出来的5个邮件:".bold()+"<br>"+wawa_matchmail(MainString)); //下面打印把邮件替换成红色的串 document.write("<BR><BR>替换为红色之后的串:".bold()+"<br>"+wawa_replacemail(MainString)); </script> </BODY> </HTML> 验证有效 日期时间 的正则表达式(已解决闰二月)^((\d{2}(([02468][048])|([13579][26]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|([1-2][0-9])))))|(\d{2}(([02468][1235679])|([13579][01345789]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\s(((0?[0-9])|([1-2][0-3]))\:([0-5]?[0-9])((\s)|(\:([0-5]?[0-9])))))?$C# Code Test: public class Class1 string s = "2003-02-29 23:59:59"; s = "2004-04-30 01:11:0"; s = "2004-04-30 0:0:0"; s = "2004-04-30 00:00:00"; //Java Code Test import java.util.regex.*; String s = "2003-02-29 23:59:59"; s = "2004-02-29 23:59:59"; s = "2004-04-31 0:59:59"; s = "2004-04-30 01:11:0"; s = "2004-04-30 0:0:0"; s = "2004-04-30 00:00:59"; 正则表达式日期时间判断正则表达式
这里是判断YYYY-MM-DD这种格式的,基本上把闰年和2月等的情况都考虑进去了,不过我已经忘了在哪里找到的。
^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$ 下面的是加了时间验证的 ^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d$ 其他几种正则表达式
"^\d+$" //非负整数(正整数 + 0) "^[0-9]*[1-9][0-9]*$" //正整数 "^((-\d+)|(0+))$" //非正整数(负整数 + 0) "^-[0-9]*[1-9][0-9]*$" //负整数 "^-?\d+$" //整数 "^\d+(\.\d+)?$" //非负浮点数(正浮点数 + 0) "^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$" //正浮点数 "^((-\d+(\.\d+)?)|(0+(\.0+)?))$" //非正浮点数(负浮点数 + 0) "^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$" //负浮点数 "^(-?\d+)(\.\d+)?$" //浮点数 "^[A-Za-z]+$" //由26个英文字母组成的字符串 "^[A-Z]+$" //由26个英文字母的大写组成的字符串 "^[a-z]+$" //由26个英文字母的小写组成的字符串 "^[A-Za-z0-9]+$" //由数字和26个英文字母组成的字符串 "^\w+$" //由数字、26个英文字母或者下划线组成的字符串 "^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$" //email地址 "^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$" //url August 22 Excel杂推荐]如何杀掉EXCEL进程
Excel.Application oExcel;
Excel.Workbooks oBooks; Object oMissing = System.Reflection.Missing.value; oExcel = new Excel.ApplicationClass(); oBooks=oExcel.Workbooks; Excel.Workbook oBook=oBooks.Add(oMissing); Excel.Worksheet oSheet = (Excel.Worksheet)oBook.ActiveSheet; //---------------------------------------------------------- oSheet.Cells[1,1]="111"; oSheet.Cells[2,1]="222"; //-------------------------------------------------------- oBook.Saved = true; oExcel.UserControl = false; string filename = DateTime.Now.Ticks.ToString(); string mm=Server.MapPath( ".")+ "\\" + filename + ".xls";//服务器保存地址 oExcel.ActiveWorkbook.SaveCopyAs (mm); //-------------------------------------------- System.Runtime.InteropServices.Marshal.ReleaseComObject (oSheet); oSheet = null; oBook.Close(false,Type.Missing,Type.Missing);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook); oBook = null; oBooks.Close();
System.Runtime.InteropServices.Marshal.ReleaseComObject (oBooks); oBooks = null; oExcel.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel); oExcel= null; //--------------------------------------------------------------- GC.Collect(); GC.WaitForPendingFinalizers(); //------------------------------------------------------------ //----------------------------------------------------------- 后来我又用了Kill的方法,代码如下。反应是“远程服务调用被拒绝” private void KillProcess(string processName) { System.Diagnostics.Process myproc= new System.Diagnostics.Process(); foreach (Process thisproc in Process.GetProcessesByName(processName)) { if(!thisproc.CloseMainWindow()) { thisproc.Kill(); } } } Private Sub killEXCEL() '为进程避免冲突,在调用EXCEL前先杀死现有EXCEL进程. Dim pProcess() As Process
pProcess = Process.GetProcesses()
Dim i As Integer
For i = 0 To pProcess.Length() - 1
If (pProcess(i).ProcessName = "EXCEL") Then
pProcess(i).Kill() '关闭进程
End If
Next
End Sub
ArrayList arr = new ArrayList(); Process[] procs = Process.GetProcessesByName("Excel"); arr.AddRange(procs); try
{ Application.Run(new MainForm()); } catch (Exception e) { ExceptionForm.Show(e); } // 杀掉死掉的 Excel 进程
procs = Process.GetProcessesByName("Excel"); foreach (Process proc in procs) { if (arr.IndexOf(proc) < 0) { proc.Kill(); } } Process.GetCurrentProcess().Kill();
Kill 强制终止进程,而 CloseMainWindow 只是请求终止。有图形界面的进程在执行时,其消息循环处于等待状态。每当操作系统向该进程发送 Windows 消息时,该消息循环执行。调用 CloseMainWindow 会向主窗口发送关闭请求,在一个设计规范的应用程序中,该请求会关闭子窗口并撤消此应用程序所有正在运行的消息循环。通过调用 CloseMainWindow 发出的退出进程的请求不强制应用程序退出。应用程序可以在退出前请求用户验证,也可以拒绝退出。若要强制应用程序退出,请使用 Kill 方法。CloseMainWindow 的行为与用户使用系统菜单关闭应用程序主窗口的行为一样。因此,通过关闭主窗口发出的退出进程的请求不强制应用程序立即退出。 如果调用 Kill,则可能丢失进程编辑的数据或分配给进程的资源。Kill 导致进程不正常终止,因而只应在必要时使用。CloseMainWindow 使进程能够有序终止并关闭所有窗口,所以对于有界面的应用程序,使用它更好。如果 CloseMainWindow 失败,则可以使用 Kill 终止进程。Kill 是终止没有图形化界面的进程的唯一方法。
只能对在本地计算机上运行的进程调用 Kill 和 CloseMainWindow。无法使远程计算机上的进程退出。仅可查看在远程计算机上运行的进程的信息。
private void KillProcess(string processName)
{ System.Diagnostics.Process myproc= new System.Diagnostics.Process(); //得到所有打开的进程 try{ foreach (Process thisproc in Process.GetProcessesByName(processName)) { if(!thisproc.CloseMainWindow()){ thisproc.Kill(); } } } catch(Exception Exc) { msg.Text+= "杀死" + processName + "失败!"; } } private void KillProcess(string processName) { System.Diagnostics.Process myproc= new System.Diagnostics.Process(); //得到所有打开的进程 try { foreach (Process thisproc in Process.GetProcessesByName(processName)) { if(!thisproc.CloseMainWindow()) { thisproc.Kill(); } MessageBox.Show("杀死" + processName + "成功!"); } }
catch(Exception Ex) { MessageBox.Show("杀死" + processName + "失败!"); } } 在调用Excel的方法之外调用GC.Collect() 就好了,进程列表中Excel的进程在GC.Collect() 后就消失了。 void DoSomething() {
...
HandleExcel();
GC.Collect() ;
}
void HandleExcel()
{
Excel.Application myExcel = new Excel.Application() ;
...
myExcel.Quit();
}
保证GC.Collect() 收集垃圾前释放EXCEL对象极其引用,确保垃圾回收器可以回收这些资源。直接杀Excel进程,但是这样有很大的问题(有可能杀掉用户自己打开的Excel)。后来用上面的方式后就好了。本方法在WinForm下的正常,asp.net中在服务器端执行Excel好像不是很好。 Excel是一个COM 对象,COM对象有一个引用计数的概念,只要计数不为0,Excel这个进程外COM对象就不会释放。 [COLOR=red]
前几天做了一个程序,打开EXCEL并保存数据库中,发现Excel进程关不了,后来采取了下面的方法,希望对大家有用: using System.Runtime.InteropServices; namespace ProduceDayReport { public class ExceptionReport : System.Windows.Forms.Form { .................. private const int WM_CLOSE=0x0010; private const int WM_QUIT=0x0012; private const int WM_DESTROY=0x0002; ..................................... .............. delegate DataTable AsynchronousManipulateDelegage(); private AsynchronousManipulateDelegage amd; [DllImport("user32.dll",CharSet=CharSet.Unicode)]
public static extern IntPtr PostMessage(IntPtr hwnd,int wMsg,IntPtr wParam,IntPtr lParam); [DllImport("user32.dll")] public static extern bool MessageBeep(BeepType beepType); [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); .....................//关键是下面的话
excel.DisplayAlerts =false;
PostMessage(excel.HWND,WM_CLOSE,new IntPtr(0),new IntPtr(0)); PostMessage(excel.HWND,WM_DESTROY,new IntPtr(0),new IntPtr(0)); ///////////
以上是我从程序内拷贝的一部分,希望大家知道该么做! 如果你用的不是officeXP,则在打开EXCEL后,做这样的工作: excel.Workbooks.Open (.......); String WndClassCaption="Microsoft Excel - "+xlsName.Substring(xlsName.LastIndexOf (@"\")+1); IntPtr hwnd_win = FindWindow("XLMAIN", WndClassCaption); if(hwnd_win==IntPtr.Zero) { hwnd_win = FindWindow("MS-SDIa",xlsName.Substring(xlsName.LastIndexOf (@"\")+1)); if(hwnd_win==IntPtr.Zero) { MessageBox.Show ("没找到窗口类 "+xlsName.Substring(xlsName.LastIndexOf (@"\")+1));
return null; } } ................... 并作如下更改: excel.DisplayAlerts =false; PostMessage((IntPtr)hwnd_win,WM_CLOSE,new IntPtr(0),new IntPtr(0)); PostMessage((IntPtr)hwnd_win,WM_DESTROY,new IntPtr(0),new IntPtr(0));[/COLOR] void DoSomething()
{
...
HandleExcel();
GC.Collect() ;
}
void HandleExcel()
{
Excel.Application myExcel = new Excel.Application() ;
...
myExcel.Quit();
}
——————————————————————————————————————
以上来自CSDN BBS
以下来自KLY.NET 的 Blog
更多信息 可以到他的博客上去看看
——————————————————————————————————————
C#操作Excel,套用模板并对数据进行分页
using System; 2using System.IO; 3using System.Data; 4using System.Reflection; 5using System.Diagnostics; 6using cfg = System.Configuration; 7//using Excel; 8 9namespace ExcelHelperTest 10{ 11 /**//// <summary> 12 /// 功能说明:套用模板输出Excel,并对数据进行分页 13 /// 作 者:Lingyun_k 14 /// 创建日期:2005-7-12 15 /// </summary> 16 public class ExcelHelper 17 { 18 protected string templetFile = null; 19 protected string outputFile = null; 20 protected object missing = Missing.Value; 21 22 /**//// <summary> 23 /// 构造函数,需指定模板文件和输出文件完整路径 24 /// </summary> 25 /// <param name="templetFilePath">Excel模板文件路径</param> 26 /// <param name="outputFilePath">输出Excel文件路径</param> 27 public ExcelHelper(string templetFilePath,string outputFilePath) 28 { 29 if(templetFilePath == null) 30 throw new Exception("Excel模板文件路径不能为空!"); 31 32 if(outputFilePath == null) 33 throw new Exception("输出Excel文件路径不能为空!"); 34 35 if(!File.Exists(templetFilePath)) 36 throw new Exception("指定路径的Excel模板文件不存在!"); 37 38 this.templetFile = templetFilePath; 39 this.outputFile = outputFilePath; 40 41 } 42 43 /**//// <summary> 44 /// 将DataTable数据写入Excel文件(套用模板并分页) 45 /// </summary> 46 /// <param name="dt">DataTable</param> 47 /// <param name="rows">每个WorkSheet写入多少行数据</param> 48 /// <param name="top">行索引</param> 49 /// <param name="left">列索引</param> 50 /// <param name="sheetPrefixName">WorkSheet前缀名,比如:前缀名为“Sheet”,那么WorkSheet名称依次为“Sheet-1,Sheet-2”</param> 51 public void DataTableToExcel(DataTable dt,int rows,int top,int left,string sheetPrefixName) 52 { 53 int rowCount = dt.Rows.Count; //源DataTable行数 54 int colCount = dt.Columns.Count; //源DataTable列数 55 int sheetCount = this.GetSheetCount(rowCount,rows); //WorkSheet个数 56 DateTime beforeTime; 57 DateTime afterTime; 58 59 if(sheetPrefixName == null || sheetPrefixName.Trim() == "") 60 sheetPrefixName = "Sheet"; 61 62 //创建一个Application对象并使其可见 63 beforeTime = DateTime.Now; 64 Excel.Application app = new Excel.ApplicationClass(); 65 app.Visible = true; 66 afterTime = DateTime.Now; 67 68 //打开模板文件,得到WorkBook对象 69 Excel.Workbook workBook = app.Workbooks.Open(templetFile,missing,missing,missing,missing,missing, 70 missing,missing,missing,missing,missing,missing,missing); 71 72 //得到WorkSheet对象 73 Excel.Worksheet workSheet = (Excel.Worksheet)workBook.Sheets.get_Item(1); 74 75 //复制sheetCount-1个WorkSheet对象 76 for(int i=1;i<sheetCount;i++) 77 { 78 ((Excel.Worksheet)workBook.Worksheets.get_Item(i)).Copy(missing,workBook.Worksheets[i]); 79 } 80 81 将源DataTable数据写入Excel#region 将源DataTable数据写入Excel 82 for(int i=1;i<=sheetCount;i++) 83 { 84 int startRow = (i - 1) * rows; //记录起始行索引 85 int endRow = i * rows; //记录结束行索引 86 87 //若是最后一个WorkSheet,那么记录结束行索引为源DataTable行数 88 if(i == sheetCount) 89 endRow = rowCount; 90 91 //获取要写入数据的WorkSheet对象,并重命名 92 Excel.Worksheet sheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i); 93 sheet.Name = sheetPrefixName + "-" + i.ToString(); 94 95 //将dt中的数据写入WorkSheet 96 for(int j=0;j<endRow-startRow;j++) 97 { 98 for(int k=0;k<colCount;k++) 99 { 100 sheet.Cells[top + j,left + k] = dt.Rows[startRow + j][k].ToString(); 101 } 102 } 103 104 //写文本框数据 105 Excel.TextBox txtAuthor = (Excel.TextBox)sheet.TextBoxes("txtAuthor"); 106 Excel.TextBox txtDate = (Excel.TextBox)sheet.TextBoxes("txtDate"); 107 Excel.TextBox txtVersion = (Excel.TextBox)sheet.TextBoxes("txtVersion"); 108 109 txtAuthor.Text = "KLY.NET的Blog"; 110 txtDate.Text = DateTime.Now.ToShortDateString(); 111 txtVersion.Text = "1.0.0.0"; 112 } 113 #endregion 114 115 //输出Excel文件并退出 116 try 117 { 118 workBook.SaveAs(outputFile,missing,missing,missing,missing,missing,Excel.XlSaveAsAccessMode.xlExclusive,missing,missing,missing,missing); 119 workBook.Close(null,null,null); 120 app.Workbooks.Close(); 121 app.Application.Quit(); 122 app.Quit(); 123 124 System.Runtime.InteropServices.Marshal.ReleaseComObject(workSheet); 125 System.Runtime.InteropServices.Marshal.ReleaseComObject(workBook); 126 System.Runtime.InteropServices.Marshal.ReleaseComObject(app); 127 128 workSheet=null; 129 workBook=null; 130 app=null; 131 132 GC.Collect(); 133 } 134 catch(Exception e) 135 { 136 throw e; 137 } 138 finally 139 { 140 Process[] myProcesses; 141 DateTime startTime; 142 myProcesses = Process.GetProcessesByName("Excel"); 143 144 //得不到Excel进程ID,暂时只能判断进程启动时间 145 foreach(Process myProcess in myProcesses) 146 { 147 startTime = myProcess.StartTime; 148 149 if(startTime > beforeTime && startTime < afterTime) 150 { 151 myProcess.Kill(); 152 } 153 } 154 } 155 156 } 157 158 159 /**//// <summary> 160 /// 获取WorkSheet数量 161 /// </summary> 162 /// <param name="rowCount">记录总行数</param> 163 /// <param name="rows">每WorkSheet行数</param> 164 private int GetSheetCount(int rowCount,int rows) 165 { 166 int n = rowCount % rows; //余数 167 168 if(n == 0) 169 return rowCount / rows; 170 else 171 return Convert.ToInt32(rowCount / rows) + 1; 172 } 173 174 175 /**//// <summary> 176 /// 将二维数组数据写入Excel文件(套用模板并分页) 177 /// </summary> 178 /// <param name="arr">二维数组</param> 179 /// <param name="rows">每个WorkSheet写入多少行数据</param> 180 /// <param name="top">行索引</param> 181 /// <param name="left">列索引</param> 182 /// <param name="sheetPrefixName">WorkSheet前缀名,比如:前缀名为“Sheet”,那么WorkSheet名称依次为“Sheet-1,Sheet-2”</param> 183 public void ArrayToExcel(string[,] arr,int rows,int top,int left,string sheetPrefixName) 184 { 185 int rowCount = arr.GetLength(0); //二维数组行数(一维长度) 186 int colCount = arr.GetLength(1); //二维数据列数(二维长度) 187 int sheetCount = this.GetSheetCount(rowCount,rows); //WorkSheet个数 188 DateTime beforeTime; 189 DateTime afterTime; 190 191 if(sheetPrefixName == null || sheetPrefixName.Trim() == "") 192 sheetPrefixName = "Sheet"; 193 194 //创建一个Application对象并使其可见 195 beforeTime = DateTime.Now; 196 Excel.Application app = new Excel.ApplicationClass(); 197 app.Visible = true; 198 afterTime = DateTime.Now; 199 200 //打开模板文件,得到WorkBook对象 201 Excel.Workbook workBook = app.Workbooks.Open(templetFile,missing,missing,missing,missing,missing, 202 missing,missing,missing,missing,missing,missing,missing); 203 204 //得到WorkSheet对象 205 Excel.Worksheet workSheet = (Excel.Worksheet)workBook.Sheets.get_Item(1); 206 207 //复制sheetCount-1个WorkSheet对象 208 for(int i=1;i<sheetCount;i++) 209 { 210 ((Excel.Worksheet)workBook.Worksheets.get_Item(i)).Copy(missing,workBook.Worksheets[i]); 211 } 212 213 将二维数组数据写入Excel#region 将二维数组数据写入Excel 214 for(int i=1;i<=sheetCount;i++) 215 { 216 int startRow = (i - 1) * rows; //记录起始行索引 217 int endRow = i * rows; //记录结束行索引 218 219 //若是最后一个WorkSheet,那么记录结束行索引为源DataTable行数 220 if(i == sheetCount) 221 endRow = rowCount; 222 223 //获取要写入数据的WorkSheet对象,并重命名 224 Excel.Worksheet sheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i); 225 sheet.Name = sheetPrefixName + "-" + i.ToString(); 226 227 //将二维数组中的数据写入WorkSheet 228 for(int j=0;j<endRow-startRow;j++) 229 { 230 for(int k=0;k<colCount;k++) 231 { 232 sheet.Cells[top + j,left + k] = arr[startRow + j,k]; 233 } 234 } 235 236 Excel.TextBox txtAuthor = (Excel.TextBox)sheet.TextBoxes("txtAuthor"); 237 Excel.TextBox txtDate = (Excel.TextBox)sheet.TextBoxes("txtDate"); 238 Excel.TextBox txtVersion = (Excel.TextBox)sheet.TextBoxes("txtVersion"); 239 240 txtAuthor.Text = "KLY.NET的Blog"; 241 txtDate.Text = DateTime.Now.ToShortDateString(); 242 txtVersion.Text = "1.0.0.0"; 243 } 244 #endregion 245 246 //输出Excel文件并退出 247 try 248 { 249 workBook.SaveAs(outputFile,missing,missing,missing,missing,missing,Excel.XlSaveAsAccessMode.xlExclusive,missing,missing,missing,missing); 250 workBook.Close(null,null,null); 251 app.Workbooks.Close(); 252 app.Application.Quit(); 253 app.Quit(); 254 255 System.Runtime.InteropServices.Marshal.ReleaseComObject(workSheet); 256 System.Runtime.InteropServices.Marshal.ReleaseComObject(workBook); 257 System.Runtime.InteropServices.Marshal.ReleaseComObject(app); 258 259 workSheet=null; 260 workBook=null; 261 app=null; 262 263 GC.Collect(); 264 } 265 catch(Exception e) 266 { 267 throw e; 268 } 269 finally 270 { 271 Process[] myProcesses; 272 DateTime startTime; 273 myProcesses = Process.GetProcessesByName("Excel"); 274 275 //得不到Excel进程ID,暂时只能判断进程启动时间 276 foreach(Process myProcess in myProcesses) 277 { 278 startTime = myProcess.StartTime; 279 280 if(startTime > beforeTime && startTime < afterTime) 281 { 282 myProcess.Kill(); 283 } 284 } 285 } 286 287 } 288 } 289} 290 处理Excel方法小结 2如何在IE中下载Excel?
——————————————————————
这里是把文件下在到客户端的方法,但是,有人说这个可以在浏览器上直接察看,一直没能发现是如何实现的,我做的一直都是提示用户保存
Response.Clear();
Response.ClearContent(); Response.ContentType = "application/vnd.ms-excel"; Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312"); Response.AddHeader("Content-Disposition", "inline;filename='Test.xls'") Response.WriteFile(filePath); Response.End(); ———————————————————————
Excel
用流的形式直接输出到客户端,这样可以满足你不在服务端生成文件的要求,速度也很快。但有一点不爽的是他不能输出复杂的表头,只能是单纯的一列一列的形式。例子如下:
SqlConnection conn=new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["conn"]);
SqlDataAdapter da=new SqlDataAdapter("select * from test",conn);
DataSet ds=new DataSet();
da.Fill(ds,"test");
DataTable dt=ds.Tables["test"];
StringWriter sw=new StringWriter();
sw.WriteLine("编号,姓名,年龄");
foreach(DataRow dr in dt.Rows) {
sw.WriteLine(dr["ID"]+"\t"+dr["Name"]+"\t"+dr["Age"]);
}
sw.Close();
Response.AddHeader("Content-Disposition", "attachment; filename=test.xls"); Response.ContentType = "application/ms-excel"; Response.ContentEncoding=System.Text.Encoding.GetEncoding("GB2312");
Response.Write(sw);
Response.End();
———————————————————————————
不要用流方式写在ie页面方法,不实用。
贴上通用代码: using System;
using System.Data; using Excel; namespace WebExcel
{ /// <summary> /// Class1 的摘要说明。 /// </summary> public class ExcelOutput { public ExcelOutput(DataView dv,string str) { // // TODO: 在此处添加构造函数逻辑 // Excel.Application excel;
int rowIndex=4; int colIndex=1; Excel._Workbook xBk;
Excel._Worksheet xSt; excel= new Excel.ApplicationClass();;
xBk = excel.Workbooks.Add(true); xSt = (Excel._Worksheet)xBk.ActiveSheet; //
//取得标题 // foreach(DataColumn col in dv.Table.Columns) { colIndex++; excel.Cells[4,colIndex] = col.ColumnName; xSt.get_Range(excel.Cells[4,colIndex],excel.Cells[4,colIndex]).HorizontalAlignment = Excel.XlVAlign.xlVAlignCenter;//设置标题格式为居中对齐 } //
//取得表格中的数据 // foreach(DataRowView row in dv) { rowIndex ++; colIndex = 1; foreach(DataColumn col in dv.Table.Columns) { colIndex ++; if(col.DataType == System.Type.GetType("System.DateTime")) { excel.Cells[rowIndex,colIndex] = (Convert.ToDateTime(row[col.ColumnName].ToString())).ToString("yyyy-MM-dd"); xSt.get_Range(excel.Cells[rowIndex,colIndex],excel.Cells[rowIndex,colIndex]).HorizontalAlignment = Excel.XlVAlign.xlVAlignCenter;//设置日期型的字段格式为居中对齐 } else if(col.DataType == System.Type.GetType("System.String")) { excel.Cells[rowIndex,colIndex] = "'"+row[col.ColumnName].ToString(); xSt.get_Range(excel.Cells[rowIndex,colIndex],excel.Cells[rowIndex,colIndex]).HorizontalAlignment = Excel.XlVAlign.xlVAlignCenter;//设置字符型的字段格式为居中对齐 } else { excel.Cells[rowIndex,colIndex] = row[col.ColumnName].ToString(); } } } // //加载一个合计行 // int rowSum = rowIndex + 1; int colSum = 2; excel.Cells[rowSum,2] = "合计"; xSt.get_Range(excel.Cells[rowSum,2],excel.Cells[rowSum,2]).HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter; // //设置选中的部分的颜色 // xSt.get_Range(excel.Cells[rowSum,colSum],excel.Cells[rowSum,colIndex]).Select(); xSt.get_Range(excel.Cells[rowSum,colSum],excel.Cells[rowSum,colIndex]).Interior.ColorIndex = 19;//设置为浅黄色,共计有56种 // //取得整个报表的标题 // excel.Cells[2,2] = str; // //设置整个报表的标题格式 // xSt.get_Range(excel.Cells[2,2],excel.Cells[2,2]).Font.Bold = true; xSt.get_Range(excel.Cells[2,2],excel.Cells[2,2]).Font.Size = 22; // //设置报表表格为最适应宽度 // xSt.get_Range(excel.Cells[4,2],excel.Cells[rowSum,colIndex]).Select(); xSt.get_Range(excel.Cells[4,2],excel.Cells[rowSum,colIndex]).Columns.AutoFit(); // //设置整个报表的标题为跨列居中 // xSt.get_Range(excel.Cells[2,2],excel.Cells[2,colIndex]).Select(); xSt.get_Range(excel.Cells[2,2],excel.Cells[2,colIndex]).HorizontalAlignment = Excel.XlHAlign.xlHAlignCenterAcrossSelection; // //绘制边框 // xSt.get_Range(excel.Cells[4,2],excel.Cells[rowSum,colIndex]).Borders.LineStyle = 1; xSt.get_Range(excel.Cells[4,2],excel.Cells[rowSum,2]).Borders[Excel.XlBordersIndex.xlEdgeLeft].Weight = Excel.XlBorderWeight.xlThick;//设置左边线加粗 xSt.get_Range(excel.Cells[4,2],excel.Cells[4,colIndex]).Borders[Excel.XlBordersIndex.xlEdgeTop].Weight = Excel.XlBorderWeight.xlThick;//设置上边线加粗 xSt.get_Range(excel.Cells[4,colIndex],excel.Cells[rowSum,colIndex]).Borders[Excel.XlBordersIndex.xlEdgeRight].Weight = Excel.XlBorderWeight.xlThick;//设置右边线加粗 xSt.get_Range(excel.Cells[rowSum,2],excel.Cells[rowSum,colIndex]).Borders[Excel.XlBordersIndex.xlEdgeBottom].Weight = Excel.XlBorderWeight.xlThick;//设置下边线加粗 // //显示效果 // excel.Visible=true; } } } 上面程序有问题,就是在asp.net中数据导入excel中,excel文件却不能显示,但任务管理器中却有此进程excel.exe
可能的解决方法:
asp.net操作excel程序,asp.net默认是没有操作dcom对象权限的,可运行dcomcfg为相应的用户分配权限(需要你的操作系统是服务器版的);
权限分配:应该允许iusr_xx(internet来宾用户)、ANONYMOUS LOGON(匿名用户)启动word的权限;并为asp.net分配可启动、存取word对象的权限。
交互方式:并且将访问方式设置为交互式。
根据上面的设置权限,用下面的方法释放.
ExcelOutput() '导出到excel
GC.Collect() '释放excel对象 还有,ExcelOutput() 与 GC.Collect() 应分开写,不可以将GC.Collect()写到ExcelOutput() 里面
以下是我在win2003 server上对dcomcfg\microsoft excel的配置:
\开始\运行\输入dcomcnfg\component service(组件服务)\computers\Dcom Config\microsoft Excel\右键\properties(属性)\ general(常规、一般): none;
security(安全):
launch permissions(启动权限):customize(自定义)\edit\使这些用户:administrator,system, asp.net,interactive,internet guest account,everyone,anonymous logon有启动的权限; access permissions(存取权限):customize\edit\使asp.ent用户有存取的权限; configuration permissions :use default(使用默认设置) identity(身份):
which user account do you want to use to run this application? the launching user(启动的用户)。这一点我觉得好像启动的用户和交互的用户都可以,因为我原来在win2000 server上用的是交互的用户,而win2003 server上用启动的用户也可以。 处理Excel方法小结这几天,因为要做Excel 报表,因此,在网上收罗了一些关于这方面的文章
——————————————————————————————————————
▲1、通过Excel的接口操作
★限制:需要安装Excel ▲1.1、采用interop方式。参考:《Creating an Excel Spreadsheet and Adding Data to It Programmatically》http://www.csharphelp.com/archives/archive241.html ▲1.2、使用反射的技术。参考:《Calling a COM Component From C# (Late Binding)》http://www.c-sharpcorner.com/1/call_com.asp ▲2、输出Excel程序可以兼容的csv格式的文件(注1)作为Excel文件。
★限制: A、只能用于输出, B、csv只支持单页(worksheet),也就是只能产生单页的Excel文件。(注2) C、不能控制格式(Format),象Cell的合并等都做不到。 ▲3、使用office 2003支持的xml导入功能,产生Excel可以导入的xml文件。
★限制: A、只能用于输出, B、不支持低版本。 ▲4、根据excel的文件格式(注3),用写二进制文件的方法产生。
▲4.1、使用第三方控件,如Aspose,网站http://www.aspose.com。 ★限制:要花钱。 ▲4.2、自己写,参考http://www.cnblogs.com/unruledboy/archive/2004/07/07/22093.html,不错的中文介绍,只是没有介绍他的资料来源,以及,也只实现了单Sheet的模式。打算走这条路可以去http://www.sourceforge.net搜索opensource关于Microsoft Office的文件格式的资料。事实上4.1提到的Aspose就是用的这些资料,只不过它用混淆器包装了一把,就开始卖钱了。 ★限制:工作量大。 孟子提醒,补充一种
▲5、使用ActiveX控件,使得用户远程操作Excel文件。参考:《如何在Web页面上直接打开、编辑、创建Office文档 》http://blog.joycode.com/kaneboy/archive/2004/11/03/37889.aspx
限制: A、客户端直接在Browser上操作Server上的文件,Server端需要配置相应权限 B、客户端需要安装office xp sp3以上或者自行注册office的activex控件"owssupp.dll" C、客户端直接在Browser上操作Server上的文件,Server端对文件内容及变更不知情,不能控制。 注1:即逗号分隔列,回车分隔行的文本格式
注2:常见“DataGrid输出到Excel”都是这种方法,例如孟宪会主页上的例子,他是重定向DataGrid的Render,但是那只是个示意,不能什么情况下都照抄,比如如果Grid里有CheckBox等太复杂的东西就不行了,最好还是自己写循环从DataTable直接生成。 注3:即Biff(Binary Interchange File Format)格式,参考《FILE: How to Create a BIFF5 File》http://support.microsoft.com/default.aspx?scid=kb;en-us;150447 其中第二点详细见《datagrid数据导出到excel文件给客户端下载的几种方法 》
http://www.cnblogs.com/lovecherry/archive/2005/03/25/125519.html /*
==========================================
以上文字来源于CSDN的BBS上
==========================================
*/
asp.net操作Excel是B/S架构开发报表中经常遇到的,现对常见操作总结如下: ASP.NET中数据库数据导入Excel并打印 ASP.NET中数据库数据导入Excel并打印 将Asp.Net页面输出到EXCEL里去 关于asp.net导出Excel ======================================== 清除应用程序进程,这里是Excel进程 ======================================== */ private void KillExcelProceed() foreach(System.Diagnostics.Process IsProcedding in ExcelProcesses) } } 注意,该段代码将搜索所有的Excel进程并关闭。 /* ================================== 另外的一种不是很成熟的方法,来关掉一个Excel进程 这个方法思路有了,但是还并不能真正的实现 ================================== */ Excel.Application xlsApp = null; try xlsBook.SaveAs(exportpath); range = null; GC.Collect(); System.Runtime.InteropServices.Marshal.ReleaseComObject(range); range = null; August 19 使用SQLSERVER的扩展存储过程实现远程备份与恢复以下为在网上摘抄过来的文章,经过试验大部分可用,但是仍然有少部分不能在SQL 中发挥作用,由于时间关系,暂时不能对其做出修改,唯有先搁置在此,等有时间的时候再来慢慢研究 —————————————————————————————————————————— 最近我在为公司的框架程序(以数据应用为导向的应用体系)做数据管理模块,这个模块的需求比较简单:备份、恢复和清理日志。我公司的软件基本上以C/S为基本架构,所以数据管理模块中两个主要的功能‘备份与恢复’都可能会在Client端操作,备份与恢复’的文件也都有可能存储在client端,因而这个数据管理模块就必须能够实现在远程备份与恢复数据库。 最近我在为公司的框架程序(以数据应用为导向的应用体系)做数据管理模块,这个模块的需求比较简单:备份、恢复和清理日志。我公司的软件基本上以C/S为基本架构,所以数据管理模块中两个主要的功能‘备份与恢复’都可能会在Client端操作,备份与恢复’的文件也都有可能存储在client端,因而这个数据管理模块就必须能够实现在远程备份与恢复数据库。 文章引用地址: |
|
|