因为工作要求, 需要对EMF文件文字内容做分析.....SO, 如下代码出现了

懒得加注释了, 反正对外接口属性就那么几个, 根据英文猜吧, 很容易的

说明一下:

  这个东西结果会对所有文字内容按照左上到右下的顺序排序(EMF内数据顺序是根据画图顺序来的, 所以不一定是什么顺序, 但是数据分析就要得到行列关系)

但是图片没有行列概念, 所以我简单借鉴了一下纯粹横排版模式, 认为2个文字元素, 只要显示范围的中线在对方范围内, 就会被认为是同一行

2015-10-19:

  1.修改了几个排序时的BUG, 增加了一个对显示区域的处理, 最大方式减少对排版的影响

  2.修改了获取SmallTextOut的处理方式

  1. {
  2. EMF文件分析单元
  3. 读取EMF内文字元素并排版
  4.  
  5. 最后修改时间 2015-10-19
  6.  
  7. by: 刘志林
  8. E-Mail: lzl_17948876@hotmail.com
  9. }
  10.  
  11. unit Comm.EMFInfo;
  12.  
  13. interface
  14.  
  15. uses
  16. System.Types, System.Generics.Collections,
  17. Vcl.Graphics;
  18.  
  19. type
  20. TEMFStrInfo = record
  21. DisplayRect: TRect; {显示区域}
  22. Text: string; {显示内容}
  23. LineKey: string; {行标记}
  24. end;
  25. PEMFStrInfo = ^TEMFStrInfo;
  26.  
  27. TEMFStrInfoList = Class
  28. private
  29. FList: TList<PEMFStrInfo>;
  30. FDic: TDictionary<string, UInt32>;
  31. FMaxHeight: Integer;
  32. FJSONStrs: string; {定位查找失败时,使用文本进行泛查找}
  33.  
  34. function GetItem(Index: UInt32): TEMFStrInfo;
  35. function GetCount: UInt32;
  36. function GetJSONStrs: string;
  37. public
  38. constructor Create;
  39. destructor Destroy; override;
  40.  
  41. procedure Append(AEMF: TMetafile; var AHeight: Integer);
  42. procedure Clear;
  43. property Count: UInt32 read GetCount;
  44. property Items[Index: UInt32]: TEMFStrInfo read GetItem;
  45. function TryGetInfo(AInfoName: string; var AInfo: TEMFStrInfo; var AIndex: UInt32): Boolean;
  46. function StrAnalyze(ALeavePattern: array of string; var AResult: string): Boolean;
  47. property JSONStr: string read GetJSONStrs;
  48. property MaxHeight: Integer read FMaxHeight;
  49. end;
  50.  
  51. implementation
  52.  
  53. uses
  54. System.SysUtils, System.Classes, System.Generics.Defaults,
  55. System.RegularExpressions,
  56. Winapi.Windows,
  57. Vcl.Printers,
  58. QJSON;
  59.  
  60. const
  61. // if set use ANSI version else UNICODE
  62. SMALLTEXT_TYPE_ANSI = $;
  63. // if set use EMR_SMALLTEXTOUT else use EMR_SMALLTEXTOUTCLIP
  64. SMALLTEXT_TYPE_WITHOUT_CLIP = $;
  65.  
  66. // Structures
  67. type
  68. EMR_SMALLTEXTOUT_HEAD = RECORD
  69. emr: emr;
  70. ptlReference: TPoint;
  71. nChars: DWORD;
  72. fuOptions: DWORD; // this record type
  73. // == SMALLTEXT_TYPE_WITHOUT_CLIP
  74. // == SMALLTEXT_TYPE_ANSI
  75. // also holds fuOptions like in the ExtTextOut function
  76. iGraphicsMode: DWORD; // See iMode parameter of SetGraphicsMode
  77. exScale: Single; { X and Y scales from Page units to .01mm units }
  78. eyScale: Single; { if graphics mode is GM_COMPATIBLE. }
  79. END;
  80.  
  81. PEMRSmallTextOutHead = ^EMR_SMALLTEXTOUT_HEAD;
  82.  
  83. EMR_SMALLTEXTOUTCLIPA = RECORD
  84. emr: emr;
  85. ptlReference: TPoint; // might be in negative numbers, so take abs
  86. nChars: DWORD;
  87. fuOptions: DWORD; // this record type
  88. // != SMALLTEXT_TYPE_WITHOUT_CLIP
  89. // == SMALLTEXT_TYPE_ANSI
  90. // also holds fuOptions like in the ExtTextOut function
  91. iGraphicsMode: DWORD; // See iMode parameter of SetGraphicsMode
  92. exScale: Single; { X and Y scales from Page units to .01mm units }
  93. eyScale: Single; { if graphics mode is GM_COMPATIBLE. }
  94. rclClip: TRect;
  95. cString: Array [ .. ] of AnsiChar;
  96. { This is followed by the string array }
  97. END;
  98.  
  99. PEMRSmallTextOutClipA = ^EMR_SMALLTEXTOUTCLIPA;
  100.  
  101. EMR_SMALLTEXTOUTCLIPW = RECORD
  102. emr: emr;
  103. ptlReference: TPoint;
  104. nChars: DWORD;
  105. fuOptions: DWORD; // this record type
  106. // != SMALLTEXT_TYPE_WITHOUT_CLIP
  107. // != SMALLTEXT_TYPE_ANSI
  108. // also holds fuOptions like in the ExtTextOut function
  109. iGraphicsMode: DWORD; // See iMode parameter of SetGraphicsMode
  110. exScale: Single; { X and Y scales from Page units to .01mm units }
  111. eyScale: Single; { if graphics mode is GM_COMPATIBLE. }
  112. rclClip: TRect;
  113. cString: Array [ .. ] of WideChar;
  114. { This is followed by the string array }
  115. END;
  116.  
  117. PEMRSmallTextOutClipW = ^EMR_SMALLTEXTOUTCLIPW;
  118.  
  119. EMR_SMALLTEXTOUTA = RECORD
  120. emr: emr;
  121. ptlReference: TPoint;
  122. nChars: DWORD;
  123. fuOptions: DWORD; // this record type
  124. // == SMALLTEXT_TYPE_WITHOUT_CLIP
  125. // == SMALLTEXT_TYPE_ANSI
  126. // also holds fuOptions like in the ExtTextOut function
  127. iGraphicsMode: DWORD; // See iMode parameter of SetGraphicsMode
  128. exScale: Single; { X and Y scales from Page units to .01mm units }
  129. eyScale: Single; { if graphics mode is GM_COMPATIBLE. }
  130. cString: Array [ .. ] of AnsiChar;
  131. { This is followed by the string array }
  132. END;
  133.  
  134. PEMRSmallTextOutA = ^EMR_SMALLTEXTOUTA;
  135.  
  136. EMR_SMALLTEXTOUTW = RECORD
  137. emr: emr;
  138. ptlReference: TPoint;
  139. nChars: DWORD;
  140. fuOptions: DWORD; // this record type
  141. // == SMALLTEXT_TYPE_WITHOUT_CLIP
  142. // != SMALLTEXT_TYPE_ANSI
  143. // also holds fuOptions like in the ExtTextOut function
  144. iGraphicsMode: DWORD; // See iMode parameter of SetGraphicsMode
  145. exScale: Single; { X and Y scales from Page units to .01mm units }
  146. eyScale: Single; { if graphics mode is GM_COMPATIBLE. }
  147. cString: Array [ .. ] of WideChar;
  148. { This is followed by the string array }
  149. END;
  150.  
  151. PEMRSmallTextOutW = ^EMR_SMALLTEXTOUTW;
  152.  
  153. var
  154. FReferenceDC: VCL.Graphics.TBitmap;
  155.  
  156. function EnumTextProc(DC: HDC; lpHTable: PHANDLETABLE; EMFR: PENHMETARECORD;
  157. nObj, lpData: Integer): Integer; stdcall;
  158.  
  159. function _IsEffeetiveRect(const ARect: TRect): Boolean;
  160. begin
  161. Result := (not ARect.IsEmpty) and (ARect.Right > ) and (ARect.Left > )
  162. and (ARect.Bottom - ARect.Top > ) and (ARect.Right - ARect.Left > );
  163. end;
  164.  
  165. procedure _ShrinkRect(var ARect: TRect; ASize: TSize);
  166. var
  167. v: Integer;
  168. begin
  169. v := ARect.Left + ASize.cx;
  170. if ARect.Right > v then
  171. ARect.Right := v;
  172. v := ARect.Top + ASize.cy;
  173. if ARect.Bottom > v then
  174. ARect.Bottom := v;
  175. end;
  176.  
  177. var
  178. nSize: TSize;
  179. nStrA: PAnsiChar;
  180. nStrW: PWideChar;
  181. nEMRTO: PEMRExtTextOut;
  182.  
  183. nEMRSTOHead: PEMRSmallTextOutHead;
  184. nEMRSTO_A: PEMRSmallTextOutA;
  185. nEMRSTO_AC: PEMRSmallTextOutClipA;
  186. nEMRSTO_W: PEMRSmallTextOutW;
  187. nEMRSTO_WC: PEMRSmallTextOutClipW;
  188.  
  189. nOTR: PEMFStrInfo;
  190. nEMFElementList: TList<PEMFStrInfo>;
  191. begin
  192. nEMFElementList := Pointer(lpData);
  193. nSize.cX := ;
  194. nSize.cY := ;
  195.  
  196. if (EMFR.iType = EMR_EXTTEXTOUTA) then
  197. begin
  198. nEMRTO := PEMRExtTextOut(EMFR);
  199. nStrA := AnsiStrAlloc(nEMRTO.EMRText.nChars + );
  200. try
  201. FillChar(nStrA^, nEMRTO.EMRText.nChars + , );
  202. Move(pointer( + Cardinal(@nEMRTO.EMRText) + nEMRTO.EMRText.offString)^,
  203. nStrA^, nEMRTO.EMRText.nChars);
  204.  
  205. New(nOTR);
  206. with nOTR^ do
  207. begin
  208. Text := Trim(nStrA);
  209. DisplayRect := nEMRTO.rclBounds;
  210. LineKey := '';
  211. end;
  212.  
  213. finally
  214. StrDispose(nStrA);
  215. end;
  216.  
  217. Winapi.Windows.GetTextExtentPoint32(FReferenceDC.Canvas.Handle,
  218. nOTR^.Text, Length(nOTR^.Text), nSize);
  219. nOTR^.DisplayRect.NormalizeRect;
  220. _ShrinkRect(nOTR^.DisplayRect, nSize);
  221.  
  222. if (nOTR^.Text <> '') and _IsEffeetiveRect(nOTR^.DisplayRect) then
  223. nEMFElementList.Add(nOTR)
  224. else
  225. Dispose(nOTR);
  226. end
  227. else if (EMFR.iType = EMR_EXTTEXTOUTW) then
  228. begin
  229. nEMRTO := PEMRExtTextOut(EMFR);
  230. nStrW := WideStrAlloc(nEMRTO.EMRText.nChars + );
  231. try
  232. FillChar(nStrW^, (nEMRTO.EMRText.nChars + ) * , );
  233. Move(pointer( + Cardinal(@nEMRTO.EMRText) + nEMRTO.EMRText.offString div )^,
  234. nStrW^, nEMRTO.EMRText.nChars * );
  235.  
  236. New(nOTR);
  237. with nOTR^ do
  238. begin
  239. Text := Trim(nStrW);
  240. DisplayRect := nEMRTO.rclBounds;
  241. LineKey := '';
  242. end;
  243.  
  244. finally
  245. StrDispose(nStrW);
  246. end;
  247.  
  248. Winapi.Windows.GetTextExtentPoint32(FReferenceDC.Canvas.Handle,
  249. nOTR^.Text, Length(nOTR^.Text), nSize);
  250. nOTR^.DisplayRect.NormalizeRect;
  251. _ShrinkRect(nOTR^.DisplayRect, nSize);
  252.  
  253. if (nOTR^.Text <> '') and _IsEffeetiveRect(nOTR^.DisplayRect) then
  254. nEMFElementList.Add(nOTR)
  255. else
  256. Dispose(nOTR);
  257. end
  258. else if EMFR.iType = EMR_SMALLTEXTOUT then
  259. begin
  260. nEMRSTOHead := PEMRSmallTextOutHead(EMFR);
  261. New(nOTR);
  262. if nEMRSTOHead.fuOptions and SMALLTEXT_TYPE_ANSI = SMALLTEXT_TYPE_ANSI then
  263. begin
  264. if nEMRSTOHead.fuOptions and SMALLTEXT_TYPE_WITHOUT_CLIP = SMALLTEXT_TYPE_WITHOUT_CLIP then
  265. begin
  266. nEMRSTO_A := Pointer(nEMRSTOHead);
  267. nStrA := AnsiStrAlloc(nEMRSTO_A^.nChars + );
  268. try
  269. FillChar(nStrA^, nEMRSTO_A^.nChars + , );
  270. Move(nEMRSTO_A^.cString[], nStrA^, nEMRSTO_A^.nChars);
  271.  
  272. with nOTR^ do
  273. begin
  274. Text := Trim(nStrA);
  275. DisplayRect := Rect(nEMRSTO_A^.ptlReference.X, nEMRSTO_A^.ptlReference.Y,
  276. MAXWORD, MAXWORD);
  277. LineKey := '';
  278. end;
  279. finally
  280. StrDispose(nStrA);
  281. end;
  282. end
  283. else
  284. begin
  285. nEMRSTO_AC := Pointer(nEMRSTOHead);
  286. nStrA := AnsiStrAlloc(nEMRSTO_AC^.nChars + );
  287. try
  288. FillChar(nStrA^, nEMRSTO_AC^.nChars + , );
  289. Move(nEMRSTO_AC^.cString[], nStrA^, nEMRSTO_AC^.nChars);
  290.  
  291. with nOTR^ do
  292. begin
  293. Text := Trim(nStrA);
  294. DisplayRect := nEMRSTO_AC^.rclClip;
  295. DisplayRect.TopLeft := nEMRSTO_AC^.ptlReference;
  296. LineKey := '';
  297. end;
  298. finally
  299. StrDispose(nStrA);
  300. end;
  301. end;
  302. end
  303. else
  304. begin
  305. if nEMRSTOHead.fuOptions and SMALLTEXT_TYPE_WITHOUT_CLIP = SMALLTEXT_TYPE_WITHOUT_CLIP then
  306. begin
  307. nEMRSTO_W := Pointer(nEMRSTOHead);
  308. nStrW := WideStrAlloc(nEMRSTO_W^.nChars + );
  309. try
  310. FillChar(nStrW^, (nEMRSTO_W^.nChars + ) * , );
  311. Move(nEMRSTO_W^.cString[], nStrW^, nEMRSTO_W^.nChars * );
  312.  
  313. with nOTR^ do
  314. begin
  315. Text := Trim(nStrW);
  316. DisplayRect := Rect(nEMRSTO_W^.ptlReference.X, nEMRSTO_W^.ptlReference.Y,
  317. MAXWORD, MAXWORD);
  318. LineKey := '';
  319. end;
  320. finally
  321. StrDispose(nStrA);
  322. end;
  323. end
  324. else
  325. begin
  326. nEMRSTO_WC := Pointer(nEMRSTOHead);
  327. nStrW := WideStrAlloc(nEMRSTO_WC^.nChars + );
  328. try
  329. FillChar(nStrW^, (nEMRSTO_WC^.nChars + ) * , );
  330. Move(nEMRSTO_WC^.cString[], nStrW^, nEMRSTO_WC^.nChars * );
  331.  
  332. with nOTR^ do
  333. begin
  334. Text := Trim(nStrW);
  335. DisplayRect := nEMRSTO_AC^.rclClip;
  336. DisplayRect.TopLeft := nEMRSTO_AC^.ptlReference;
  337. LineKey := '';
  338. end;
  339. finally
  340. StrDispose(nStrA);
  341. end;
  342. end;
  343. end;
  344.  
  345. Winapi.Windows.GetTextExtentPoint32(FReferenceDC.Canvas.Handle,
  346. nOTR^.Text, Length(nOTR^.Text), nSize);
  347. nOTR^.DisplayRect.NormalizeRect;
  348. _ShrinkRect(nOTR^.DisplayRect, nSize);
  349.  
  350. if (nOTR^.Text <> '') and _IsEffeetiveRect(nOTR^.DisplayRect) then
  351. nEMFElementList.Add(nOTR)
  352. else
  353. Dispose(nOTR);
  354. end;
  355.  
  356. Result := ;
  357. end;
  358.  
  359. type
  360. TEMFStrInfoCompare = class(TComparer<PEMFStrInfo>)
  361. public
  362. function Compare(const Left, Right: PEMFStrInfo): Integer; override;
  363. end;
  364.  
  365. { TEMFStrInfoCompare }
  366.  
  367. function TEMFStrInfoCompare.Compare(const Left, Right: PEMFStrInfo): Integer;
  368. var
  369. nCPLeft, nCPRight: TPoint;
  370. nLIR, nRIL: Int8;
  371. nLineKey: string;
  372. begin
  373. nCPLeft := Left^.DisplayRect.CenterPoint;
  374. nCPRight := Right^.DisplayRect.CenterPoint;
  375.  
  376. if nCPLeft.Y <= Right^.DisplayRect.Top then
  377. nLIR := -
  378. else if nCPLeft.Y >= Right^.DisplayRect.Bottom then
  379. nLIR :=
  380. else
  381. nLIR := ;
  382.  
  383. if nCPRight.Y <= Left^.DisplayRect.Top then
  384. nRIL := -
  385. else if nCPRight.Y >= Left^.DisplayRect.Bottom then
  386. nRIL :=
  387. else
  388. nRIL := ;
  389.  
  390. if (nLIR = ) or (nRIL = ) then
  391. begin
  392. if Left^.LineKey <> '' then
  393. Right^.LineKey := Left^.LineKey
  394. else if Right^.LineKey <> '' then
  395. Left^.LineKey := Right^.LineKey
  396. else
  397. begin
  398. Left^.LineKey := TGUID.NewGuid.ToString;
  399. Right^.LineKey := Left^.LineKey;
  400. end;
  401.  
  402. {有任意leftright在另一方区域内的, 认为在同一行, 通过x位置判断排序}
  403. if nCPLeft.X < nCPRight.X then {根据左侧判断位置}
  404. Result := -
  405. else if nCPLeft.X > nCPRight.X then
  406. Result :=
  407. else if nCPLeft.Y < nCPRight.Y then
  408. Result := -
  409. else if nCPLeft.Y > nCPRight.Y then
  410. Result :=
  411. else
  412. Result := ;
  413. end
  414. else
  415. begin
  416. Result := nLIR;
  417. end;
  418. end;
  419.  
  420. { TEMFStrInfoList }
  421.  
  422. procedure TEMFStrInfoList.Append(AEMF: TMetafile; var AHeight: Integer);
  423. var
  424. nList: TList<PEMFStrInfo>;
  425. nInfoExists: Boolean;
  426. nCheckPoint: TPoint;
  427. i: Integer;
  428. nCompare: TEMFStrInfoCompare;
  429. nPI: PEMFStrInfo;
  430. nTmpLineKey, nTmpJSONStr: string;
  431. nJ, nJLine: TQJson;
  432. begin
  433. nList := TList<PEMFStrInfo>.Create;
  434. try
  435. {读取文件元素存入列表}
  436. EnumEnhMetafile(, AEMF.Handle, @EnumTextProc, Pointer(nList), Rect(, , , ));
  437.  
  438. nCompare := TEMFStrInfoCompare.Create;
  439. try
  440. {排序}
  441. try
  442. nList.Sort(nCompare);
  443. finally
  444. nCompare.Free;
  445. end;
  446. except
  447. end;
  448.  
  449. {计算最大高度, 元素名称存入字典}
  450. AHeight := ;
  451. nJ := TQJson.Create;
  452. try
  453. // nJ.TryParse(FJSONStrs);
  454. nJ.DataType := jdtArray;
  455. nJLine := nil;
  456. nTmpLineKey := '';
  457. for i := to nList.Count - do
  458. begin
  459. nPI := nList[i];
  460. if nPI^.LineKey = '' then
  461. nPI^.LineKey := TGUID.NewGuid.ToString; {没有相同行标记的给一个标记}
  462. {需要换行}
  463. if (nTmpLineKey = '') or (not SameText(nTmpLineKey, nPI^.LineKey)) then
  464. nJLine := nil;
  465. {当前行标记}
  466. nTmpLineKey := nPI^.LineKey;
  467.  
  468. if nPI^.DisplayRect.Bottom > AHeight then
  469. AHeight := nPI^.DisplayRect.Bottom;
  470.  
  471. OffsetRect(nPI^.DisplayRect, , FMaxHeight);
  472. FDic.AddOrSetValue(nPI^.Text, FList.Add(nPI));
  473.  
  474. if (nJLine = nil) then
  475. nJLine := nJ.AddArray('');
  476.  
  477. nJLine.Add.AsString := nPI^.Text;
  478. end;
  479. nTmpJSONStr := nJ.Encode(False);
  480. nTmpJSONStr := Copy(nTmpJSONStr, , Length(nTmpJSONStr) - );
  481. if FJSONStrs = '' then
  482. FJSONStrs := nTmpJSONStr
  483. else
  484. FJSONStrs := FJSONStrs + ',' + nTmpJSONStr;
  485. finally
  486. nJ.Free;
  487. end;
  488. FMaxHeight := FMaxHeight + AHeight;
  489. finally
  490. nList.Free;
  491. end;
  492. end;
  493.  
  494. procedure TEMFStrInfoList.Clear;
  495. var
  496. i: Integer;
  497. begin
  498. FMaxHeight := ;
  499. FJsonStrs := '';
  500. for i := to FList.Count - do
  501. Dispose(FList[i]);
  502. FList.Clear;
  503. FDic.Clear;
  504. end;
  505.  
  506. constructor TEMFStrInfoList.Create;
  507. begin
  508. FList := TList<PEMFStrInfo>.Create;
  509. FDic := TDictionary<string, UInt32>.Create;
  510. FMaxHeight := ;
  511. FJsonStrs := '';
  512. end;
  513.  
  514. destructor TEMFStrInfoList.Destroy;
  515. var
  516. i: Integer;
  517. begin
  518. for i := to FList.Count - do
  519. Dispose(FList[i]);
  520. FList.Free;
  521. FDic.Free;
  522. inherited;
  523. end;
  524.  
  525. function TEMFStrInfoList.GetCount: UInt32;
  526. begin
  527. Result := FList.Count;
  528. end;
  529.  
  530. function TEMFStrInfoList.GetItem(Index: UInt32): TEMFStrInfo;
  531. begin
  532. Result := FList[Index]^;
  533. end;
  534.  
  535. function TEMFStrInfoList.GetJSONStrs: string;
  536. begin
  537. Result := '[' + FJSONStrs + ']';
  538. end;
  539.  
  540. function TEMFStrInfoList.StrAnalyze(ALeavePattern: array of string; var AResult: string): Boolean;
  541.  
  542. function _RegExAnalyze(AData, APattern: string): string;
  543. var
  544. nMatches: TMatchCollection;
  545. begin
  546. nMatches := TRegEx.Matches(AData, APattern, [roMultiLine]);
  547. if nMatches.Count > then
  548. Result := nMatches.Item[].Value;
  549. end;
  550.  
  551. var
  552. i: Integer;
  553. nTmpData: string;
  554. begin
  555. AResult := '';
  556. try
  557. nTmpData := FJSONStrs;
  558. for i := Low(ALeavePattern) to High(ALeavePattern) do
  559. begin
  560. nTmpData := _RegExAnalyze(nTmpData, ALeavePattern[i]);
  561. if nTmpData = '' then
  562. Break;
  563. end;
  564. AResult := nTmpData;
  565. except
  566. on E: Exception do
  567. raise Exception.CreateFmt('正则分析失败[%s]', [E.Message]);
  568. end;
  569. Result := AResult <> '';
  570. end;
  571.  
  572. function TEMFStrInfoList.TryGetInfo(AInfoName: string; var AInfo: TEMFStrInfo; var AIndex: UInt32): Boolean;
  573. begin
  574. Result := FDic.TryGetValue(AInfoName, AIndex);
  575. if Result then
  576. AInfo := FList[AIndex]^;
  577. end;
  578.  
  579. initialization
  580. FReferenceDC := VCL.Graphics.TBitmap.Create;
  581. with FReferenceDC do
  582. begin
  583. PixelFormat := pf24bit;
  584. Width := ;
  585. Height := ;
  586. end;
  587.  
  588. finalization
  589. FreeAndNil(FReferenceDC);
  590.  
  591. end.

获取EMF文件内全部文字, 并按照左上到右下的顺序排序的更多相关文章

  1. 从运行时的工作空间获取EMF文件(IFILE)

    //EMFFILE_URI为EMF文件的URI String uriString = EMFFILE_URI.trimFragment().toPlatformString(true); if (ur ...

  2. python 获取excel文件内sheet名称列表

    xl = pd.ExcelFile('foo.xls') xl.sheet_names # see all sheet names xl.parse(sheet_name) # read a spec ...

  3. 使用GridView来获取xml文件数据

    在任何一个系统中,数据的读取和编辑都是至关重要的.无论你是CS还是BS,都需要对数据进行操作.其实 我们可以发现,很多软件和系统最终都是对于数据库中数据的处理.之前在CS的学习过程中我们接触到了很多 ...

  4. 编写Java程序,在硬盘中选取一个 txt 文件,读取该文档的内容后,追加一段文字“[ 来自新华社 ]”,保存到一个新的 txt 文件内

    查看本章节 查看作业目录 需求说明: 在硬盘中选取一个 txt 文件,读取该文档的内容后,追加一段文字"[ 来自新华社 ]",保存到一个新的 txt 文件内 实现思路: 创建 Sa ...

  5. XML序列化 判断是否是手机 字符操作普通帮助类 验证数据帮助类 IO帮助类 c# Lambda操作类封装 C# -- 使用反射(Reflect)获取dll文件中的类型并调用方法 C# -- 文件的压缩与解压(GZipStream)

    XML序列化   #region 序列化 /// <summary> /// XML序列化 /// </summary> /// <param name="ob ...

  6. 在Autodesk Vault 2014中使用VDF(Vault Development Framework) API获取所有文件的属性信息

      这几天在玩儿Vault API, 从Autodesk Vault 2014开始提供了Vault Development Framework(VDF) API,让开发工作更简单了.在Vault 20 ...

  7. 关于 MAXScript 获取全部文件

    MAXScript 官方文档里关于获取文件夹下所有文件的方法 fn getFilesRecursive root pattern = ( dir_array = GetDirectories (roo ...

  8. SNF开发平台WinForm之十三-单独从服务器上获取PDF文件进行显示-SNF快速开发平台3.3-Spring.Net.Framework

    1运行效果: 2开发实现: 如果需要单独显示PDF文件时用下面代码去实现,指定url地址. 地址: . 获取附件管理的实体对象: List<KeyValuePair<string, obj ...

  9. vue 双语言切换中,data内翻译文字不正常切换的解决方案

    背景 有这么一个登录页面,相关功能如下: 支持双语言,点击切换语言 表单内部有一个自定义的select,里面option的label.value都是的名字由外部提供:其中预设的option的label ...

随机推荐

  1. XSS攻击及防御

    XSS又称CSS,全称Cross SiteScript,跨站脚本攻击,是Web程序中常见的漏洞,XSS属于被动式且用于客户端的攻击方式,所以容易被忽略其危害性.其原理是攻击者向有XSS漏洞的网站中输入 ...

  2. Nginx与Apache的比较

    Nginx与Apache的比较 Nginx相对于Apache的优点 轻量级.同样起web服务,比apache占用更少的资源和内存 抗并发.nginx处理请求是异步非阻塞,而apache则是阻塞型.在高 ...

  3. Caffe初试(三)使用caffe的cifar10网络模型训练自己的图片数据

    由于我涉及一个车牌识别系统的项目,计划使用深度学习库caffe对车牌字符进行识别.刚开始接触caffe,打算先将示例中的每个网络模型都拿出来用用,当然这样暴力的使用是不会有好结果的- -||| ,所以 ...

  4. TFS二次开发系列:三、TFS二次开发的第一个实例

    首先我们需要认识TFS二次开发的两大获取服务对象的类. 他们分别为TfsConfigurationServer和TfsTeamProjectCollection,他们的不同点在于可以获取不同的TFS ...

  5. NIO初识

    Java编程中的NIO,俗称new I/O,是在JDK1.4版本之后开始引入的,在JDK1.4之前,Java服务端大多使用同步阻塞式来处理网络请求,在低流量.低并发情况还能抗住,在如今互联网时代,信息 ...

  6. Pyqt+QRcode 生成 识别 二维码

    1.生成二维码 python生成二维码是件很简单的事,使用第三方库Python QRCode就可生成二维码,我用Pyqt给QRcode打个壳 一.python-qrcode介绍 python-qrco ...

  7. [转载]使用PyQt来编写第一个Python GUI程序

    转载自:http://python.jobbole.com/81276/ 英文版出处:http://pythonforengineers.com/your-first-gui-app-with-pyt ...

  8. ajax下载文件

    得到所有Post数据: var postData=Request.Form.ToString() 构建JS代码 // Ajax 文件下载jQuery.download = function(url, ...

  9. 彻底解决m2eclipse之Unable to update index for central

    原文链接:https://my.oschina.net/itblog/blog/208581 maven是个好东西,eclipse上的maven插件m2eclipse也非常方便,但是最近这个东西经常无 ...

  10. PV 与 并发数 之间的故事

    PV: Page View UV: Unique Visitor 在一些已经上线的项目中,运营会统计每日的PV,UV,IP 等数据 而根据PV量,可以推算出一个相对较科学的并发数,来作为负载测试的一个 ...