procedure BatchDBGridEhDataToExcel(DBGrid:TDBGridEh;Title:string;DrawGridLine:Boolean; RangeFields:TStringList);
该过程将TDBGridEh中的数据导出到Excel中。本过程能够将TDBGridEh的多层表头导出到Excel中,并且还能够将给定字段的相同的值合并一起,例如:
参数:
DBGrid:TDBGridEh为要导出数据的网格控件,Title为报表的标题,DrawGridLine控制是否绘制网格线,RangeFields为需要合并数据的字段列表。

在“打印”按钮的OnClick事件中填写如下代码:
var RangeFields:TStringList; begin file://true为绘制网格线// RangeFields:=TStringList.Create; RangeFields.Add('TJDWMC'); try if RadioButton1.Checked then BatchDBGridEhDataToExcel(DBGrid_JTGS,Caption,true,RangeFields) else BatchDBGridEhDataToExcel(DBGrid_LYJ,Caption,true,RangeFields); finally RangeFields.Free; end; end;
执行后启动Excel程序,显示界面如下所示:
注意:在合并网格时会出现是“否合并网格”对话框,请电击“是”即可。

需要声明的常量:
const file://Excel用到的常量// xlHairline = $00000001; xlMedium = $FFFFEFD6; xlThick = $00000004; xlThin = $00000002; const file://Excel用到的常量// xlContinuous = $00000001; xlDash = $FFFFEFED; xlDashDot = $00000004; xlDashDotDot = $00000005; xlDot = $FFFFEFEA; xlDouble = $FFFFEFE9; xlSlantDashDot = $0000000D; xlLineStyleNone = $FFFFEFD2; const xlAll = $FFFFEFF8; xlAutomatic = $FFFFEFF7; xlBoth = $00000001; xlCenter = $FFFFEFF4; xlChecker = $00000009; xlCircle = $00000008; xlCorner = $00000002; xlCrissCross = $00000010; xlCross = $00000004; xlDiamond = $00000002; xlDistributed = $FFFFEFEB; xlDoubleAccounting = $00000005; xlFixedValue = $00000001; xlFormats = $FFFFEFE6; xlGray16 = $00000011; xlGray8 = $00000012; xlGrid = $0000000F; xlHigh = $FFFFEFE1; xlInside = $00000002; xlJustify = $FFFFEFDE; xlLightDown = $0000000D; xlLightHorizontal = $0000000B; xlLightUp = $0000000E; xlLightVertical = $0000000C; xlLow = $FFFFEFDA; xlManual = $FFFFEFD9; xlMinusValues = $00000003; xlModule = $FFFFEFD3; xlNextToAxis = $00000004; xlNone = $FFFFEFD2; xlNotes = $FFFFEFD0; xlOff = $FFFFEFCE; xlOn = $00000001; xlPercent = $00000002; xlPlus = $00000009; xlPlusValues = $00000002; xlSemiGray75 = $0000000A; xlShowLabel = $00000004; xlShowLabelAndPercent = $00000005; xlShowPercent = $00000003; xlShowValue = $00000002; xlSimple = $FFFFEFC6; xlSingle = $00000002; xlSingleAccounting = $00000004; xlSolid = $00000001; xlSquare = $00000001; xlStar = $00000005; xlStError = $00000004; xlToolbarButton = $00000002; xlTriangle = $00000003; xlGray25 = $FFFFEFE4; xlGray50 = $FFFFEFE3; xlGray75 = $FFFFEFE2; xlBottom = $FFFFEFF5; xlLeft = $FFFFEFDD; xlRight = $FFFFEFC8; xlTop = $FFFFEFC0; xl3DBar = $FFFFEFFD; xl3DSurface = $FFFFEFF9; xlBar = $00000002; xlColumn = $00000003; xlCombination = $FFFFEFF1; xlCustom = $FFFFEFEE; xlDefaultAutoFormat = $FFFFFFFF; xlMaximum = $00000002; xlMinimum = $00000004; xlOpaque = $00000003; xlTransparent = $00000002; xlBidi = $FFFFEC78; xlLatin = $FFFFEC77; xlContext = $FFFFEC76; xlLTR = $FFFFEC75; xlRTL = $FFFFEC74; xlFullScript = $00000001; xlPartialScript = $00000002; xlMixedScript = $00000003; xlMixedAuthorizedScript = $00000004; xlVisualCursor = $00000002; xlLogicalCursor = $00000001; xlSystem = $00000001; xlPartial = $00000003; xlHindiNumerals = $00000003; xlBidiCalendar = $00000003; xlGregorian = $00000002; xlComplete = $00000004; xlScale = $00000003; xlClosed = $00000003; xlColor1 = $00000007; xlColor2 = $00000008; xlColor3 = $00000009; xlConstants = $00000002; xlContents = $00000002; xlBelow = $00000001; xlCascade = $00000007; xlCenterAcrossSelection = $00000007; xlChart4 = $00000002; xlChartSeries = $00000011; xlChartShort = $00000006; xlChartTitles = $00000012; xlClassic1 = $00000001; xlClassic2 = $00000002; xlClassic3 = $00000003; xl3DEffects1 = $0000000D; xl3DEffects2 = $0000000E; xlAbove = $00000000; xlAccounting1 = $00000004; xlAccounting2 = $00000005; xlAccounting3 = $00000006; xlAccounting4 = $00000011; xlAdd = $00000002; xlDebugCodePane = $0000000D; xlDesktop = $00000009; xlDirect = $00000001; xlDivide = $00000005; xlDoubleClosed = $00000005; xlDoubleOpen = $00000004; xlDoubleQuote = $00000001; xlEntireChart = $00000014; xlExcelMenus = $00000001; xlExtended = $00000003; xlFill = $00000005; xlFirst = $00000000; xlFloating = $00000005; xlFormula = $00000005; xlGeneral = $00000001; xlGridline = $00000016; xlIcons = $00000001; xlImmediatePane = $0000000C; xlInteger = $00000002; xlLast = $00000001; xlLastCell = $0000000B; xlList1 = $0000000A; xlList2 = $0000000B; xlList3 = $0000000C; xlLocalFormat1 = $0000000F; xlLocalFormat2 = $00000010; xlLong = $00000003; xlLotusHelp = $00000002; xlMacrosheetCell = $00000007; xlMixed = $00000002; xlMultiply = $00000004; xlNarrow = $00000001; xlNoDocuments = $00000003; xlOpen = $00000002; xlOutside = $00000003; xlReference = $00000004; xlSemiautomatic = $00000002; xlShort = $00000001; xlSingleQuote = $00000002; xlStrict = $00000002; xlSubtract = $00000003; xlTextBox = $00000010; xlTiled = $00000001; xlTitleBar = $00000008; xlToolbar = $00000001; xlVisible = $0000000C; xlWatchPane = $0000000B; xlWide = $00000003; xlWorkbookTab = $00000006; xlWorksheet4 = $00000001; xlWorksheetCell = $00000003; xlWorksheetShort = $00000005; xlAllExceptBorders = $00000006; xlLeftToRight = $00000002; xlTopToBottom = $00000001; xlVeryHidden = $00000002; xlDrawingObject = $0000000E; const
{ The list of VtFont styles }
{ FontStyleConstants }
VtFontStyleBold = 1; VtFontStyleItalic = 2; VtFontStyleOutline = 4;
{ The list of VtFont effects }
{ FontEffectsConstants }
VtFontEffectStrikeThrough = 256; VtFontEffectUnderline = 512;
-------------------------------------------------------------------------------------------------------
procedure SetTitleInExcel(Sheet:OleVariant; FirstRow,FirstCol,LastRow,LastCol:integer;Title:string); var RangeStr:string; Range:Variant; begin Sheet.Activate; RangeStr:=GetRangStr(FirstRow,FirstCol,LastRow,LastCol); Range:=Sheet.Range[RangeStr]; Range.Merge(true); Range.Font.Size:=14; Range.Font.Name:='黑体'; Range.Font.FontStyle:=VtFontStyleBold; Range.HorizontalAlignment := xlCenter; Range.VerticalAlignment := xlCenter; Range.Value:=Title; end;
function GetRangStr(FirstRow,FirstCol,LastRow,LastCol:integer):string; var iA,iB:integer; begin result:=''; if (FirstRow<1)or(LastRow<1)or(LastRow<1)or(LastCol<1) then Exit;
iA:=FirstCol div 26; iB:=FirstCol mod 26; if iB=0 then begin iA:=iA-1; iB:=26; end;
if iA=0 then result:=Chr(Ord('A')+iB-1)+IntToStr(FirstRow)+':' else result:=Chr(Ord('A')+iA-1)+Chr(Ord('A')+iB-1)+IntToStr(FirstRow)+':';
iA:=LastCol div 26; iB:=LastCol mod 26; if iB=0 then begin iA:=iA-1; iB:=26; end;
if iA=0 then result:=result+Chr(Ord('A')+iB-1)+IntToStr(LastRow) else result:=result+Chr(Ord('A')+iA-1)+Chr(Ord('A')+iB-1)+IntToStr(LastRow); end;
procedure DrawGridInExcel(Sheet:OleVariant; FirstRow,FirstCol,LastRow,LastCol:integer); var RangeStr:string; Range:Variant; begin Sheet.Activate; RangeStr:=GetRangStr(FirstRow,FirstCol,LastRow,LastCol); Range:=Sheet.Range[RangeStr]; Range.Columns.Interior.ColorIndex:=0; Range.Borders.LineStyle:=xlHairline; Range.Font.Size:=8; Range.Font.Name:='楷体_GB2312'; end;
procedure TransMuiltTitleStr(Text: string;List:TStrings); var str:string; Index:integer; begin str:=Text; List.Clear; Index:=Pos('|',str); while Index>0 do begin List.Add(Copy(str,1,Index-1)); str:=Copy(str,Index+1,Length(str)-Index); Index:=Pos('|',str); end; if Index=0 then List.Add(str); end;
Function My_DataSetToExcelSheet(DataSet:TDataSet;m_Fields:tstringlist;Sheet:OleVariant; RangeFields:TStrings;DrawGridLine:Boolean;var FirstRow,FirstCol:integer): Boolean; var DataFirstRow,Row,Col,i,j :Integer; BK:TBookMark; LastValue,CurrentValue:string; RangeStr:string; Range:Variant; RangeFirstRow,RangeFirstCol:integer; List:TStringList; file://用于存储复合标题各个行的字符串列表// MaxTVCount:integer;//标题最大纵向行数// begin Result := False; if not Dataset.Active then exit; BK:=DataSet.GetBookMark; DataSet.DisableControls; Sheet.Activate; try file://定制复杂列标题// MaxTVCount:=0; List:=TStringList.Create; try Col:=FirstCol; for i:=0 to m_Fields.Count-1 do begin Row:=FirstRow;
TransMuiltTitleStr(DataSet.FieldByName(m_Fields.Strings[i]).DisplayLabel,List); if List.Count>MaxTVCount then MaxTVCount:=List.Count;
for j:=0 to List.Count-1 do begin Sheet.Cells(Row,Col) :=List.Strings[j]; Inc(Row); end; Inc(Col); end; finally List.Free; end;
file://绘制网格// if DrawGridLine then begin DrawGridInExcel(Sheet,FirstRow,1,FirstRow+DataSet.RecordCount+MaxTVCount-1, m_Fields.Count); end; file://横向合并标题网格// for i:=FirstRow to FirstRow+MaxTVCount-1 do begin file://记录当前行// Row:=i; file://如果列数大于零则计算// if m_Fields.Count>0 then begin RangeFirstCol:=1; LastValue:=Sheet.Cells.Item[Row,RangeFirstCol];
for j:=2 to m_Fields.Count do begin CurrentValue:=Sheet.Cells.Item[Row,j]; if CurrentValue<>LastValue then begin file://合并单元格// if LastValue<>'' then begin RangeStr:=GetRangStr(Row,RangeFirstCol,Row,j-1); Range:=Sheet.Range[RangeStr]; file://Range.Merge(false); Range.mergecells:=true; Range.WrapText:=true; Range.HorizontalAlignment := xlCenter; Range.VerticalAlignment := xlCenter; Range.Value:=LastValue; end;
RangeFirstCol:=j; LastValue:=Sheet.Cells.Item[Row,RangeFirstCol]; end; end; file://合并单元格// if LastValue<>'' then begin RangeStr:=GetRangStr(Row,RangeFirstCol,Row,m_Fields.Count); Range:=Sheet.Range[RangeStr]; // Range.Merge(false); Range.mergecells:=true; Range.WrapText:=true; Range.HorizontalAlignment := xlCenter; Range.VerticalAlignment := xlCenter; Range.Value:=LastValue; end;
RangeFirstCol:=m_Fields.Count+1; LastValue:=Sheet.Cells.Item[Row,RangeFirstCol]; end; end; file://纵向合并标题网格,将纵向最后一个不为空值的格与其下面所有空格合并到一起// if MaxTVCount>1 then for i:=1 to m_Fields.Count do for j:=FirstRow+MaxTVCount-1 downto FirstRow do begin CurrentValue:=Sheet.Cells.Item[j,i]; if CurrentValue<>'' then begin if j<>FirstRow+MaxTVCount-1 then begin file://合并单元格// RangeStr:=GetRangStr(j,i,FirstRow+MaxTVCount-1,i); Range:=Sheet.Range[RangeStr]; Range.Merge(false); Range.WrapText:=true; Range.HorizontalAlignment := xlCenter; Range.VerticalAlignment := xlCenter; Range.Value:=CurrentValue; end; Break; end; end;
file://数据的第一条的索引号// DataFirstRow:=FirstRow+MaxTVCount;
Row:=DataFirstRow;
file://填写表格内容// DataSet.First; while Not DataSet.Eof do begin Col:=1;
for i:=0 to m_Fields.count-1 do begin Sheet.Cells(Row,Col):=DataSet.FieldByName(m_Fields.Strings[i]).AsString; Inc(Col); end;
Row:=Row+1;
DataSet.Next; end;
if m_Fields.count>0 then Col:=Col-1; file://合并项目字段的值// for i:=0 to RangeFields.Count-1 do begin Col:=m_Fields.IndexOf(RangeFields.Strings[i])+1; if DataSet.RecordCount>0 then begin RangeFirstRow:=DataFirstRow; LastValue:=Sheet.Cells.Item[RangeFirstRow,Col];
for j:=1 to DataSet.RecordCount-1 do begin CurrentValue:=Sheet.Cells.Item[DataFirstRow+j,Col]; if CurrentValue<>LastValue then begin file://合并单元格// RangeStr:=GetRangStr(RangeFirstRow,Col,DataFirstRow+j-1,Col); Range:=Sheet.Range[RangeStr]; Range.Merge(false); Range.WrapText:=true; Range.HorizontalAlignment := xlCenter; Range.VerticalAlignment := xlCenter; Range.Value:=LastValue;
RangeFirstRow:=DataFirstRow+j; LastValue:=Sheet.Cells.Item[RangeFirstRow,Col]; end; end; file://合并单元格// RangeStr:=GetRangStr(RangeFirstRow,Col,DataFirstRow+DataSet.RecordCount-1,Col); Range:=Sheet.Range[RangeStr]; Range.Merge(false); Range.WrapText:=true; Range.HorizontalAlignment := xlCenter; Range.VerticalAlignment := xlCenter; Range.Value:=LastValue;
RangeFirstRow:=DataFirstRow+DataSet.RecordCount; LastValue:=Sheet.Cells.Item[RangeFirstRow,Col]; end; end;
Result := True; finally DataSet.GotoBookMark(BK); DataSet.EnableControls; end; end;
procedure BatchDBGridEhDataToExcel(DBGrid:TDBGridEh;Title:string;DrawGridLine:Boolean; RangeFields:TStringList); var s:tstringlist; i:integer; begin if not DBGrid.DataSource.DataSet.active then begin MessageDlg('主结果集没有打开!',mtWarning,[mbok],0); exit; end; s:=tstringlist.create; try for i:=0 to DBGrid.Columns.Count-1 do begin s.Add(DBGrid.Columns[i].FieldName); DBGrid.DataSource.DataSet.FieldByName( DBGrid.Columns[i].FieldName).DisplayLabel:= DBGrid.Columns[i].Title.Caption; end; My_DataSetToExcel(DBGrid.DataSource.DataSet,s,RangeFields,DrawGridLine,true, Title,''); finally s.free; end; end;

|