using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Collections; using System.Drawing; using FastReport.Export; using FastReport.Utils; using FastReport; using FastReport.Format; namespace FastReport.Export.BIFF8 { internal class OLE_Property { internal UInt32 propertyID; internal UInt32 propertyOffset; internal UInt32 propertyType; internal object propertyData; } internal class OLE_Stream : BIFF8_Stream { private DirectoryEntry entry; public OLE_Stream(CompoundDocumentHeader document_header, DirectoryEntry dir) : base(document_header, dir) { entry = dir; } internal void Read() { UInt16 byte_order = ReadUshort(); UInt16 Version = ReadUshort(); UInt32 System = ReadUint(); byte[] UID = ReadBytes(16); UInt32 PropetiesCount = ReadUint(); int up_level_position = (int)this.Position; for (int i = 0; i < PropetiesCount; i++) { this.Position = up_level_position; byte[] FormatID = ReadBytes(16); UInt32 Offset = ReadUint(); up_level_position = (int)this.Position; this.Position = (int)Offset; int top_border = (int)this.Position; UInt32 cbSection = ReadUint(); // Section size in bytes UInt32 cProreties = ReadUint(); // Number of Properties in the Set OLE_Property[] summary_properties = new OLE_Property[cProreties]; for (int j = 0; j < cProreties; j++) { summary_properties[j] = new OLE_Property(); summary_properties[j].propertyID = ReadUint(); summary_properties[j].propertyOffset = ReadUint(); } for (int j = 0; j < cProreties; j++) { this.Position = top_border + (int)summary_properties[j].propertyOffset; summary_properties[j].propertyType = ReadUint(); switch (summary_properties[j].propertyType) { case 0x0002: // uInt32 summary_properties[j].propertyData = ReadUint(); break; //case 0x1e00: // // ReadBytes(0x10 - sizeof(UInt32)); // break; //case 0x4000: // // ReadBytes(0x0c - sizeof(UInt32)); // break; //case 0x4001: // // ReadBytes(0x0c - sizeof(UInt32)); // break; case 0x001e: // ansi string UInt32 strlen = ReadUint(); string value = ""; for (int k = 0; k < strlen; k++) { value += (char)ReadByte(); } break; case 0x0040: // DateTime UInt32 time_low = ReadUint(); UInt32 time_high = ReadUint(); break; case 0x0003: // Access rights summary_properties[j].propertyData = ReadUint(); break; case 0x000b: // Unknown property summary_properties[j].propertyData = ReadUint(); break; case 0x101e: // Unknown property ReadBytes(0x29 - sizeof(UInt32)); break; case 0x100c: ReadBytes(0x23 - sizeof(UInt32)); break; default: //throw new Exception("Unimplemented property type"); Console.WriteLine("Unimplemented property type: " + summary_properties[j].propertyType.ToString()); break; } int prop_size; if (j + 1 < cProreties) { prop_size = (int)(summary_properties[j + 1].propertyOffset - summary_properties[j].propertyOffset); } else { prop_size = (int)(cbSection - summary_properties[j].propertyOffset); } } } } } internal class BIFF8_Window1 { UInt16 hPos; UInt16 vPos; UInt16 width; UInt16 height; UInt16 flags; UInt16 active_worksheet; UInt16 first_visible_tab; UInt16 selected_sheet_count; UInt16 worksheet_tab_width; internal void Read(StreamHelper stream) { hPos = stream.ReadUshort(); vPos = stream.ReadUshort(); width = stream.ReadUshort(); height = stream.ReadUshort(); flags = stream.ReadUshort(); active_worksheet = stream.ReadUshort(); first_visible_tab = stream.ReadUshort(); selected_sheet_count = stream.ReadUshort(); worksheet_tab_width = stream.ReadUshort(); } internal void Write(StreamHelper stream) { stream.WriteUshort(0x003d); // WINDOW1 stream.WriteUshort(0x0012); // Payload size stream.WriteUshort(0x0168); // Horizontal position stream.WriteUshort(0x0069); // Vertical position width = 15600; height = 8190; stream.WriteUshort(width); stream.WriteUshort(height); stream.WriteUshort(0x0038); // Window flags stream.WriteUshort(0x0000); // Active worksheet stream.WriteUshort(0x0000); // First visible tab stream.WriteUshort(0x0001); // Selected sheet count stream.WriteUshort(0x0258); // Worksheet tab width } } internal class BIFF8_Font { internal UInt16 fontHeight; internal UInt16 options; internal UInt16 colourIdx; internal UInt16 fontWeight; internal UInt16 escapement; internal byte underlineType; internal byte fontFamily; internal byte characterSet; internal string fontName; /* internal void Debug(StreamWriter debug, int idx) { debug.Write("\nFont {0}", idx); debug.Write("\n\tName\t{0}", FontName); debug.Write("\n\tSize\t{0}", FontHeight); debug.Write("\n\tWeight\t{0}", FontWeight); debug.Write("\n\tColor\t{0}", ColourIdx); debug.Write("\n\tOptions\t{0:X2}", Options); debug.Write("\n\tEsc\t{0:X2}", Escapement); debug.Write("\n\tUnderline\t{0:X}", UnderlineType); debug.Write("\n\tFamily\t{0:X}", FontFamily); debug.Write("\n\tCharacterSet\t{0:X}\n", CharacterSet); } */ internal void Read(StreamHelper stream) { fontHeight = stream.ReadUshort(); options = stream.ReadUshort(); colourIdx = stream.ReadUshort(); fontWeight = stream.ReadUshort(); escapement = stream.ReadUshort(); underlineType = (byte)stream.ReadByte(); fontFamily = (byte)stream.ReadByte(); characterSet = (byte)stream.ReadByte(); stream.SkipBytes(1); fontName = stream.ReadUnicodeString(true); } internal void Write(StreamHelper stream) { stream.WriteUshort(0x0031); ushort payload_size = (ushort)(14 + 2 + fontName.Length * 2); stream.WriteUshort(payload_size); stream.WriteUshort(fontHeight); stream.WriteUshort(options); stream.WriteUshort(colourIdx); stream.WriteUshort(fontWeight); stream.WriteUshort(escapement); stream.WriteByte(underlineType); stream.WriteByte(fontFamily); stream.WriteByte(characterSet); stream.SkipBytes(1); stream.WriteUnicodeString(fontName, true); } public BIFF8_Font(string name, UInt16 height, UInt16 weight) { this.fontName = name; this.fontHeight = height; this.fontWeight = weight; } public BIFF8_Font(ExportIEMStyle style, ushort ColorIdx) { Font f = style.Font; this.fontName = f.Name; this.fontHeight = (ushort)(12 * Math.Round(f.Height * DrawUtils.ScreenDpiFX)); this.fontWeight = (ushort)((f.Bold ? 70 : 12) * f.SizeInPoints); this.fontFamily = 0; this.colourIdx = ColorIdx; this.underlineType = (byte)(f.Underline ? 1 : 0); this.options = (ushort)((f.Italic ? 2 : 0) | (f.Bold ? 1 : 0)); } } internal class BIFF8_Format { UInt16 format_index; string format_string; /* internal void Debug(StreamWriter debug, int idx) { debug.Write("\nFormat {0}", idx); debug.Write("\n\tIndex\t{0}", format_index); debug.Write("\n\tString\t{0}\n", format_string); } */ internal BIFF8_Format(UInt16 format_index, string format_string) { this.format_index = format_index; this.format_string = format_string; } internal void Write(StreamHelper stream) { stream.WriteUshort(0x041e); ushort payload_size = (ushort)(2 + (ushort)stream.SizeUnicodeString(format_string, false)); stream.WriteUshort(payload_size); // Size stream.WriteUshort(format_index); stream.WriteUnicodeString(format_string, false); } } internal class BIFF8_Hyperlink { // TODO: always has default value? internal ushort rwFirst = 0; internal ushort rwLast = 0; internal ushort colFirst = 0; internal ushort colLast = 0; internal uint optionFlags; string huperlink; bool is_url; private void Write_URL(StreamHelper stream) { byte[] GUID_Moniker = { 0xE0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE, 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B }; stream.WriteBytes(GUID_Moniker); uint calc_len = (uint)(huperlink.Length * 4); stream.WriteUint(calc_len); for (int i = 0; i < huperlink.Length; i++) { stream.WriteUshort((ushort)huperlink[i]); } stream.WriteUshort(0); // NULL-terminated } private void Write_HyperlinkToLocalFile(StreamHelper stream) { byte[] GUID_FileMoniker = { 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 }; stream.WriteBytes(GUID_FileMoniker); // There is no way to make portable implementation of this function } internal void Write(StreamHelper stream) { byte[] GUID_StdLink = { 0xd0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE, 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B }; optionFlags = 0x3; ushort record_size = (ushort)(32 + (16 + 4 + huperlink.Length * 2 + 2)); stream.WriteUshort(0x01b8); // Hyperlink stream.WriteUshort(record_size); // Record size stream.WriteUshort(rwFirst); stream.WriteUshort(rwLast); stream.WriteUshort(colFirst); stream.WriteUshort(colLast); stream.WriteBytes(GUID_StdLink); stream.WriteUint(2); // Unknown value defined in BIFF8 spec stream.WriteUint(optionFlags); Write_URL(stream); } internal BIFF8_Hyperlink(string URL) { this.huperlink = URL; is_url = URL.Contains("://"); } } internal class BIFF8_ExtendedFormat { internal UInt16 font_index; internal UInt16 format_index; internal UInt16 xf_type; internal byte alignment_and_break; internal byte rotation; internal byte identation; internal byte flags; internal UInt32 borders; internal UInt32 attributes; UInt16 pattern_colors; private string BorderStyle(uint st, uint color_idx) { string name = ""; switch (st) { case 0: name = "None"; break; case 1: name = "Thin"; break; case 2: name = "Medium"; break; case 3: name = "Dashed"; break; case 4: name = "Dotted"; break; case 5: name = "Thick"; break; case 6: name = "Double"; break; case 7: name = "Hair"; break; case 8: name = "MediumDashed"; break; case 10: name = "ThinDashDotted"; break; case 11: name = "MediumDashDotted"; break; case 12: name = "ThinDashDotDotted"; break; case 13: name = "MediumDashDotDotted"; break; case 14: name = "SlantedMediumDashDotted"; break; default: name = "Unknown "; break; } name = name + " " + color_idx.ToString(); return name; } private string HorizontalAlign(int ha) { string text = ""; switch (ha) { case 0: text = "General"; break; case 1: text = "Left"; break; case 2: text = "Centered"; break; case 3: text = "Right"; break; case 4: text = "Filled"; break; case 5: text = "Justified"; break; case 6: text = "CAS"; break; // Centred across selection case 7: text = "Distributed"; break; default: text = "Unknown"; break; } return text; } private string VerticalAlign(int va) { string text = ""; switch (va) { case 0: text = "Top"; break; case 1: text = "Centered"; break; case 2: text = "Bottom"; break; case 3: text = "Justified"; break; case 4: text = "Distributed"; break; default: text = "Unknown"; break; } return text; } private string Pattern(uint patt) { string text = ""; switch (patt) { case 0: text = "None"; break; case 1: text = "Solid"; break; case 2: text = "Chess"; break; case 3: text = "HorThick"; break; case 4: text = "VerThick"; break; case 5: text = "ChessThick"; break; case 6: text = "Hor"; break; case 7: text = "Ver"; break; case 8: text = "DiagBack"; break; case 9: text = "Diag"; break; case 10: text = "Cross"; break; case 11: text = "CrossDiag"; break; default: text = "Unknown"; break; } return text; } /* internal void Debug(StreamWriter debug, int idx) { debug.Write("\nXF {0}", idx); debug.Write("\n\tFormInd\t{0}", format_index); debug.Write("\n\tFontIdx\t{0}", font_index); debug.Write("\n\tType\t{0:X2}", xf_type); debug.Write("\n\tFlags\t{0:X}", flags); debug.Write("\n\tAlign\t{0:X} H={1} V={2} {3} {4}", alignment_and_break, HorizontalAlign(alignment_and_break & 0x03), VerticalAlign((alignment_and_break >> 4) & 0x03), (alignment_and_break & 0x8) == 0 ? "" : "WordWarp", (alignment_and_break & 0x80) == 0 ? "" : "Justify" ); debug.Write("\n\tBorders\t{0:X4} L={1} R={2} T={3} B={4}", borders, BorderStyle(0xf & borders, 0xff & (borders >> 16)), BorderStyle(0xf & (borders >> 4), 0xff & (borders >> 23)), BorderStyle(0xf & (borders >> 8), 0xff & (attributes)), BorderStyle(0xf & (borders >> 12), 0xff & (attributes >> 7)) ); debug.Write("\n\tAttrib\t{0:X4} Pattern {1}", attributes, Pattern(attributes >> 26)); debug.Write("\n\tPattern\t{0:X2}", pattern_colors); } */ internal void Read(StreamHelper stream) { font_index = stream.ReadUshort(); format_index = stream.ReadUshort(); xf_type = stream.ReadUshort(); alignment_and_break = (byte)stream.ReadByte(); rotation = (byte)stream.ReadByte(); identation = (byte)stream.ReadByte(); flags = (byte)stream.ReadByte(); borders = stream.ReadUint(); attributes = stream.ReadUint(); pattern_colors = stream.ReadUshort(); } internal void Write(StreamHelper stream) { stream.WriteUshort(0x00e0); // XF extended format stream.WriteUshort(0x0014); // Record size stream.WriteUshort(font_index); stream.WriteUshort(format_index); stream.WriteUshort(xf_type); stream.WriteByte(alignment_and_break); stream.WriteByte(rotation); stream.WriteByte(identation); stream.WriteByte(flags); stream.WriteUint(borders); stream.WriteUint(attributes); stream.WriteUshort(pattern_colors); } internal BIFF8_ExtendedFormat() { this.xf_type = 0xfff5; this.flags = 0xf7; this.alignment_and_break = 0x9; } internal BIFF8_ExtendedFormat( ushort font_idx, ushort format_idx, ushort type, byte flags, byte align) { this.font_index = font_idx; this.format_index = format_idx; this.xf_type = type; this.flags = flags; this.alignment_and_break = align; } private byte GetAngle(ExportIEMStyle EStyle) { int angle = EStyle.Angle; if (angle != 0 && angle <= 90) { angle = 90 + angle; } else if (angle >= 270) { angle = 360 - angle; } else { angle = 0; } return (byte)angle; } private byte GetAlignment(ExportIEMStyle EStyle) { byte result = (byte)(EStyle.WordWrap == true ? 0x8 : 0x0); switch (EStyle.HAlign) { case HorzAlign.Center: result |= 2; break; case HorzAlign.Justify: result |= 5; break; case HorzAlign.Left: result |= 1; break; case HorzAlign.Right: result |= 3; break; } switch (EStyle.VAlign) { case VertAlign.Top: result |= (0 << 4); break; case VertAlign.Center: result |= (1 << 4); break; case VertAlign.Bottom: result |= (2 << 4); break; } return result; } private byte GetBorderLineStyle(BorderLine line) { int style = 0; switch (line.Style) { case LineStyle.Solid: style = line.Width <= 1 ? 1 : line.Width <= 3 ? 2 : 5; break; case LineStyle.Dash: style = line.Width <= 3 ? 3 : 8; break; case LineStyle.Dot: style = 4; break; case LineStyle.DashDot: style = line.Width <= 3 ? 10 : 11; break; case LineStyle.DashDotDot: style = line.Width <= 3 ? 12 : 13; break; case LineStyle.Double: style = 6; break; } return (byte)style; } private void GetBorders(Workbook workbook, ExportIEMStyle EStyle, out uint result, out uint attrib) { result = 0; attrib = 0; if ((EStyle.Border.Lines & BorderLines.Left) == BorderLines.Left) { result |= (uint)(GetBorderLineStyle(EStyle.Border.LeftLine)) | ((0x7f & (((uint)workbook.AddColor(EStyle.Border.LeftLine.Color)))) << 16); } if ((EStyle.Border.Lines & BorderLines.Right) == BorderLines.Right) { result |= (uint)(GetBorderLineStyle(EStyle.Border.RightLine) << 4) | ((uint)workbook.AddColor(EStyle.Border.RightLine.Color)) << 23; ; } if ((EStyle.Border.Lines & BorderLines.Top) == BorderLines.Top) { result |= ((uint)(GetBorderLineStyle(EStyle.Border.TopLine)) << 8); attrib |= 0x7f & ((uint)workbook.AddColor(EStyle.Border.TopLine.Color)); } if ((EStyle.Border.Lines & BorderLines.Bottom) == BorderLines.Bottom) { result |= (uint)(GetBorderLineStyle(EStyle.Border.BottomLine) << 12); attrib |= ((uint)workbook.AddColor(EStyle.Border.BottomLine.Color)) << 7; } } private Color MixColors(Color s, Color e) { return Color.FromArgb((int)(s.A + e.A) / 2, (int)(s.R + e.R) / 2, (int)(s.G + e.G) / 2, (int)(s.B + e.B) / 2); } internal BIFF8_ExtendedFormat( bool style, ushort font_index, ExportIEMStyle EStyle, Workbook workbook, int indFormat ) { this.font_index = font_index; switch (EStyle.Format.Name) { case "Currency": format_index = 7; break; case "Date": case "Number": format_index = (ushort)indFormat; break; case "General": default: format_index = 0; break; } this.alignment_and_break = this.GetAlignment(EStyle); this.rotation = this.GetAngle(EStyle); this.identation = 0; ushort fill_color = 0; if (style) { this.xf_type = 0xfff7; this.flags = 0x00; // 0xf7; } else { this.xf_type = 0x00; this.flags = 0xfc; } this.GetBorders(workbook, EStyle, out this.borders, out this.attributes); if (EStyle.Fill is SolidFill) { if (EStyle.FillColor.A != 0) { this.attributes |= (1 << 26); fill_color = workbook.AddColor(EStyle.FillColor); this.pattern_colors = (ushort)(fill_color | (ushort)(fill_color << 7)); } } else if (EStyle.Fill is LinearGradientFill) { this.attributes |= (1 << 26); LinearGradientFill lgf = EStyle.Fill as LinearGradientFill; fill_color = workbook.AddColor(MixColors(lgf.StartColor, lgf.EndColor)); ; } else if (EStyle.Fill is PathGradientFill) { this.attributes |= (1 << 26); PathGradientFill pgf = EStyle.Fill as PathGradientFill; fill_color = workbook.AddColor(MixColors(pgf.CenterColor, pgf.EdgeColor)); ; } else if (EStyle.Fill is HatchFill) { this.attributes |= (1 << 26); HatchFill hf = EStyle.Fill as HatchFill; fill_color = workbook.AddColor(MixColors(hf.ForeColor, hf.BackColor)); ; } else if (EStyle.Fill is GlassFill) { this.attributes |= (1 << 26); GlassFill hf = EStyle.Fill as GlassFill; fill_color = workbook.AddColor(hf.Color); ; } else { this.attributes |= (1 << 26); fill_color = workbook.AddColor(Color.LightGray); } this.pattern_colors = (ushort)(fill_color | (ushort)(fill_color << 7)); } } internal class BIFF8_Style { UInt16 style_attrib; string style_str; byte style_id; byte level; /* internal void Debug(StreamWriter debug, int idx) { debug.Write("\n\nStyles {0}", idx); debug.Write("\n\tID\t{0}", style_id); debug.Write("\n\tAttrib\t{0:X2}", style_attrib); debug.Write("\n\tLevel\t{0}", level); if (style_str != null) { debug.Write("\n\tName\t {0}", style_str); } debug.Write("\n"); } */ internal void Read(StreamHelper stream) { style_attrib = stream.ReadUshort(); if (0 == (style_attrib & 0x8000)) { style_str = stream.ReadUnicodeString(false); } else { style_id = (byte)stream.ReadByte(); level = (byte)stream.ReadByte(); } } internal void Write(StreamHelper stream) { stream.WriteUshort(0x0293); if (0 == (style_attrib & 0x8000)) { ushort payload_size = (ushort)(2 + (ushort)stream.SizeUnicodeString(style_str, false)); stream.WriteUshort(payload_size); // Size stream.WriteUshort(style_attrib); stream.WriteUnicodeString(style_str, false); } else { stream.WriteUshort(0x0004); // Size stream.WriteUshort(style_attrib); stream.WriteByte(style_id); stream.WriteByte(level); } } internal BIFF8_Style() { style_attrib = 0x8000; style_id = 0; level = 0xff; } internal BIFF8_Style(ushort idx, ExportIEMStyle style) { style_attrib = (ushort)(0x8000 + idx); style_id = 0; // Normal level = 0xff; } } internal class BIFF8_SharedStringTable { UInt32 total_number_strings; UInt32 number_following_strings; ArrayList shared_strings = new ArrayList(); /* internal void Debug(StreamWriter debug) { debug.Write("\n\nShared trings"); for (int i = 0; i < shared_strings.Count; i++) { debug.Write("\n\t{0}\t{1}", i, shared_strings[i]); } } */ enum StringStates { Start, Work, Brake }; internal int Read(StreamHelper stream, int RecordSize) { int total_size = (int)stream.Position; total_number_strings = stream.ReadUint(); number_following_strings = stream.ReadUint(); uint rest = number_following_strings; long stream_position = stream.Position; string str = ""; int num_rich_runs = 0; StringStates state = StringStates.Start; UInt16 Char_Count = 0; byte grBit = 0; byte options; RecordSize -= 8; while (rest != 0) { switch (state) { case StringStates.Start: long tnp_position = stream.Position; Char_Count = (ushort)stream.ReadUshort(); options = (byte)stream.ReadByte(); if ((options & 0x8) != 0) num_rich_runs = stream.ReadUshort(); grBit = (byte)(options & 0x1); if (Char_Count != 0) state = StringStates.Work; else { shared_strings.Add(""); rest--; } RecordSize -= (int)(stream.Position - tnp_position); break; case StringStates.Brake: UInt16 RecordID = stream.ReadUshort(); RecordSize = stream.ReadUshort(); if (RecordID != 0x003c) { stream.Position -= 8; break; } grBit = (byte)stream.ReadByte(); RecordSize--; state = StringStates.Work; break; case StringStates.Work: char ch; if (grBit == 0) { ch = (char)stream.ReadByte(); RecordSize--; } else { ch = (char)stream.ReadUshort(); RecordSize -= 2; } str += ch; Char_Count--; if (Char_Count == 0) { state = StringStates.Start; shared_strings.Add(str); str = ""; rest--; } break; } if (RecordSize == 0) state = StringStates.Brake; } total_size = (int)stream.Position - total_size; return total_size; } internal void Write(StreamHelper stream) { ushort payload_size = 8; number_following_strings = (uint)shared_strings.Count; bool begin = true; long size_position; for (int index = 0; index < number_following_strings;) { if (begin) { stream.WriteUshort(0x00fc); size_position = stream.Position; stream.WriteUshort(0); stream.WriteUint(total_number_strings); stream.WriteUint(number_following_strings); begin = false; } else { stream.WriteUshort(0x003c); size_position = stream.Position; stream.WriteUshort(0); } while (payload_size < 8224) { if (index >= shared_strings.Count) break; ushort string_size = (ushort)stream.SizeUnicodeString((string)shared_strings[index], false); if (payload_size + string_size < 8224) { stream.WriteUnicodeString((string)shared_strings[index], false); payload_size += string_size; index++; } else { break; } } long curent_position = stream.Position; stream.Position = size_position; stream.WriteUshort(payload_size); payload_size = 0; stream.Position = curent_position; } } internal void Add(string str) { shared_strings.Add(str); } internal uint Count { get { return (uint)shared_strings.Count; } } } internal abstract class BIFF8_CellData { internal long stream_position; internal ushort cell_data_size; internal abstract void Read(StreamHelper stream); internal abstract void Write(StreamHelper stream); } internal class BIFF8_Blank : BIFF8_CellData { UInt16 blank_row_idx; UInt16 blank_col_idx; UInt16 blank_xf_idx; /* internal void Debug(StreamWriter debug, int idx) { debug.Write("\n\n\tBlank \t{0}", idx); debug.Write("\n\t\tRow\t{0}", blank_row_idx); debug.Write("\n\t\tCol\t{0}", blank_col_idx); debug.Write("\n\t\tBlankXF\t{0}", blank_xf_idx); debug.Write("\n"); } */ internal override void Read(StreamHelper stream) { stream_position = stream.Position; blank_row_idx = stream.ReadUshort(); blank_col_idx = stream.ReadUshort(); blank_xf_idx = stream.ReadUshort(); cell_data_size = (ushort)(stream.Position - stream_position); } internal override void Write(StreamHelper stream) { stream_position = stream.Position; stream.WriteUshort(0x0201); // BLANK stream.WriteUshort(0x0006); // record size stream.WriteUshort(blank_row_idx); stream.WriteUshort(blank_col_idx); stream.WriteUshort(blank_xf_idx); cell_data_size = (ushort)(stream.Position - stream_position); } internal BIFF8_Blank() { } internal BIFF8_Blank(ushort row_idx, ushort col_idx, ushort xf_idx) { this.blank_row_idx = row_idx; this.blank_col_idx = col_idx; this.blank_xf_idx = xf_idx; } } internal class BIFF8_MulBlank : BIFF8_CellData { UInt16 blank_row; UInt16 first_blank_column; UInt16 last_blank_column; UInt16[] fx_indexes; UInt16 recordSize; /* internal void Debug(StreamWriter debug, int idx) { debug.Write("\n\n\tMulBlank \t{0}", idx); debug.Write("\n\t\tRow\t{0}", blank_row); debug.Write("\n\t\tFirstCol\t{0}", first_blank_column); debug.Write("\n\t\tKastCol\t{0}", last_blank_column); for (int i = 0; i < fx_indexes.Length; i++) debug.Write("\n\t\tfx[{0}]\t{1}", i, fx_indexes[i]); debug.Write("\n"); } */ internal override void Read(StreamHelper stream) { stream_position = stream.Position; blank_row = stream.ReadUshort(); first_blank_column = stream.ReadUshort(); int count = ((recordSize - sizeof(UInt16) * 3) >> 1); fx_indexes = new ushort[count]; for (int i2fx = 0; i2fx < count; i2fx++) { fx_indexes[i2fx] = stream.ReadUshort(); } last_blank_column = stream.ReadUshort(); if (last_blank_column - first_blank_column + 1 != count) throw new Exception("BIFF8_MulBlank: file structue error"); cell_data_size = (ushort)(stream.Position - stream_position); } internal override void Write(StreamHelper stream) { stream_position = stream.Position; ushort rec_size = (ushort)((fx_indexes.Length << 1) + sizeof(UInt16) * 3); stream.WriteUshort(0x00be); // MULBLANK stream.WriteUshort(rec_size); // record size stream.WriteUshort(blank_row); stream.WriteUshort(first_blank_column); for (int i2fx = 0; i2fx < fx_indexes.Length; i2fx++) { stream.WriteUshort(fx_indexes[i2fx]); } stream.WriteUshort(last_blank_column); cell_data_size = (ushort)(stream.Position - stream_position); } public BIFF8_MulBlank(UInt16 RecordSize) { this.recordSize = RecordSize; } public BIFF8_MulBlank(UInt16 blank_row, UInt16 first_blank_column, UInt16 last_blank_column, UInt16 fx_index) { int count = last_blank_column - first_blank_column + 1; this.blank_row = blank_row; this.first_blank_column = first_blank_column; this.last_blank_column = last_blank_column; this.fx_indexes = new ushort[count]; for (int i = 0; i < count; i++) this.fx_indexes[i] = fx_index; } } internal class BIFF8_FloatNumber : BIFF8_CellData { ushort rw; ushort col; ushort ifxe; double rk; internal override void Read(StreamHelper stream) { stream_position = stream.Position; rw = stream.ReadUshort(); col = stream.ReadUshort(); ifxe = stream.ReadUshort(); rk = stream.ReadDouble(); } internal override void Write(StreamHelper stream) { stream.WriteUshort(0x0203); stream.WriteUshort(14); // record size stream.WriteUshort(rw); stream.WriteUshort(col); stream.WriteUshort(ifxe); stream.WriteDouble(rk); } internal BIFF8_FloatNumber() { } internal BIFF8_FloatNumber(ushort row_idx, ushort col_idx, ushort xf_idx, decimal obj) { this.rw = row_idx; this.col = col_idx; this.ifxe = xf_idx; this.rk = ((double)obj); } } internal class BIFF8_Number : BIFF8_CellData { UInt16 rw; UInt16 col; UInt16 ifxe; UInt32 rk; /* internal void Debug(StreamWriter debug, int idx) { debug.Write("\n\n\tNumber \t{0}", idx); debug.Write("\n\t\tRow\t{0}", rw); debug.Write("\n\t\tol\t{0}", col); debug.Write("\n\t\tXF\t{0}", ifxe); debug.Write("\n\t\tEncVal\t{0}", rk); debug.Write("\n"); } */ internal override void Read(StreamHelper stream) { rw = stream.ReadUshort(); col = stream.ReadUshort(); ifxe = stream.ReadUshort(); rk = stream.ReadUint(); } internal override void Write(StreamHelper stream) { stream.WriteUshort(0x027e); stream.WriteUshort(10); // record size stream.WriteUshort(rw); stream.WriteUshort(col); stream.WriteUshort(ifxe); stream.WriteUint(rk); } internal BIFF8_Number() { } internal BIFF8_Number(ushort row_idx, ushort col_idx, ushort xf_idx, float obj) { rw = row_idx; col = col_idx; ifxe = xf_idx; rk = (UInt32)obj; rk <<= 2; } internal BIFF8_Number(ushort row_idx, ushort col_idx, ushort xf_idx, DateTime dt) { rw = row_idx; col = col_idx; ifxe = xf_idx; DateTime centuryBegin = new DateTime(1899, 12, 30); long elapsedTicks = dt.Ticks - centuryBegin.Ticks; TimeSpan elapsedSpan = new TimeSpan(elapsedTicks); rk = (uint)((elapsedSpan.Days << 2) | 2); } internal BIFF8_Number(ushort row_idx, ushort col_idx, ushort xf_idx, Decimal value) { rw = row_idx; col = col_idx; ifxe = xf_idx; long date = (long)(value * 100); rk = (UInt32)date; rk <<= 2; rk |= 3; } } internal class FIFF8_CellRange : BIFF8_CellData { UInt16 first_row_idx; UInt16 last_row_idx; UInt16 first_col_idx; UInt16 last_col_idx; internal override void Read(StreamHelper stream) { first_row_idx = stream.ReadUshort(); last_row_idx = stream.ReadUshort(); first_col_idx = stream.ReadUshort(); last_col_idx = stream.ReadUshort(); } internal override void Write(StreamHelper stream) { stream.WriteUshort(first_row_idx); stream.WriteUshort(last_row_idx); stream.WriteUshort(first_col_idx); stream.WriteUshort(last_col_idx); } internal FIFF8_CellRange() { } internal FIFF8_CellRange(UInt16 first_row, UInt16 last_row, UInt16 first_col, UInt16 last_col) { this.first_row_idx = first_row; this.last_row_idx = last_row; this.first_col_idx = first_col; this.last_col_idx = last_col; } } internal class BIFF8_LabelSST : BIFF8_CellData { internal UInt16 label_row_idx; internal UInt16 label_col_idx; internal UInt16 label_xf_idx; internal UInt32 label_sst_idx; /* internal void Debug(StreamWriter debug, int idx) { debug.Write("\n\n\tLabel \t{0}", idx); debug.Write("\n\t\tRow\t{0}", label_row_idx); debug.Write("\n\t\tCol\t{0}", label_col_idx); debug.Write("\n\t\tXF\t{0}", label_xf_idx); debug.Write("\n\t\tSST_IDX\t{0}", label_sst_idx); debug.Write("\n"); } */ internal override void Read(StreamHelper stream) { stream_position = stream.Position; label_row_idx = stream.ReadUshort(); label_col_idx = stream.ReadUshort(); label_xf_idx = stream.ReadUshort(); label_sst_idx = stream.ReadUint(); } internal override void Write(StreamHelper stream) { stream_position = stream.Position; stream.WriteUshort(0x00fd); // LABELSST stream.WriteUshort(0x000a); // record size stream.WriteUshort(label_row_idx); stream.WriteUshort(label_col_idx); stream.WriteUshort(label_xf_idx); stream.WriteUint(label_sst_idx); cell_data_size = (ushort)(stream.Position - stream_position); } internal BIFF8_LabelSST() { } internal BIFF8_LabelSST(ushort row_idx, ushort col_idx, ushort xf_idx, uint sst_idx) { this.label_row_idx = row_idx; this.label_col_idx = col_idx; this.label_xf_idx = xf_idx; this.label_sst_idx = sst_idx; } } internal class BIFF8_Colinfo { internal UInt16 first_column; internal UInt16 last_column; internal UInt16 column_width; internal UInt16 index_to_xf_recod; internal UInt16 colinfo_options; /* internal void Debug(StreamWriter debug, int idx) { debug.Write("\n\nColinfo"); debug.Write("\n\tFirst\t{0}", first_column); debug.Write("\n\tLast\t{0}", last_column); debug.Write("\n\tWidth\t{0}", column_width); debug.Write("\n\tXF\t{0}", index_to_xf_recod); debug.Write("\n\tOptions\t{0:X2}", colinfo_options); debug.Write("\n"); } */ internal void Read(StreamHelper stream) { first_column = stream.ReadUshort(); last_column = stream.ReadUshort(); column_width = stream.ReadUshort(); index_to_xf_recod = stream.ReadUshort(); colinfo_options = stream.ReadUshort(); stream.SkipBytes(2); } internal void Write(StreamHelper stream) { stream.WriteUshort(0x007d); // COLINFO stream.WriteUshort(0x000c); // payload size stream.WriteUshort(first_column); stream.WriteUshort(last_column); stream.WriteUshort(column_width); stream.WriteUshort(index_to_xf_recod); stream.WriteUshort(colinfo_options); stream.SkipBytes(2); } internal BIFF8_Colinfo() { } internal BIFF8_Colinfo(ushort Column, ushort Width, ushort index_xf) { first_column = Column; last_column = Column; column_width = Width; index_to_xf_recod = index_xf; colinfo_options = 0; } } internal class RowBlock : ArrayList { internal ArrayList cells = new ArrayList(); UInt16[] first_cell_offsets; Int32 relative_offset_to_first_row; internal void Read(StreamHelper stream) { int current_position = (int)stream.Position; relative_offset_to_first_row = stream.ReadInt(); // int count_of_rows = (int)current_sheet.last_row - (int)current_sheet.first_row; // fix me first_cell_offsets = stream.ReadUshorts(this.Count); current_position -= relative_offset_to_first_row; current_position += 0x14; int row_index = 0; for (row_index = 0; row_index < first_cell_offsets.Length;) { current_position += first_cell_offsets[row_index]; BIFF8_Row curr_row = this[row_index++] as BIFF8_Row; int next_position; if (row_index < first_cell_offsets.Length) next_position = current_position + first_cell_offsets[row_index]; else next_position = int.MaxValue; foreach (BIFF8_CellData cell in cells) { if (cell.stream_position >= current_position && cell.stream_position < next_position) { curr_row.Add(cell); } } } } internal void Write(StreamHelper stream) { foreach (BIFF8_Row row in this) { row.Write(stream); } foreach (BIFF8_Row row in this) { foreach (BIFF8_CellData cell in row) { cell.Write(stream); } } stream.WriteUshort(0x00d7); // DBCELL ushort payload_size = (ushort)(4 + 2 * this.Count); stream.WriteUshort(payload_size); BIFF8_Row first_row = this[0] as BIFF8_Row; uint first_row_offset = (uint)(stream.Position - first_row.last_position); stream.WriteUint(first_row_offset); ushort cell_offset = (ushort)(this.Count * 0x10); foreach (BIFF8_Row row in this) { if (row.Count == 0) continue; BIFF8_CellData first_cell = row[0] as BIFF8_CellData; stream.WriteUshort(cell_offset); cell_offset = first_cell.cell_data_size; } } } internal class BIFF8_Row : ArrayList { internal UInt16 row_index; internal UInt16 first_col_index; internal UInt16 last_col_index; internal UInt16 row_height_bitfield; internal UInt32 row_options; internal int last_position; /* internal void Debug(StreamWriter debug, int idx) { debug.Write("\n\nRow"); debug.Write("\n\tIndex\t{0}", row_index); debug.Write("\n\tFirst\t{0}", first_col_index); debug.Write("\n\tLast\t{0}", last_col_index); debug.Write("\n\tOptions\t{0:X4}", row_options); debug.Write("\n\tHeight\t{0:X2}", row_height_bitfield); debug.Write("\n"); } */ internal void Read(StreamHelper stream) { row_index = stream.ReadUshort(); first_col_index = stream.ReadUshort(); last_col_index = stream.ReadUshort(); row_height_bitfield = stream.ReadUshort(); stream.SkipBytes(4); row_options = stream.ReadUint(); last_position = (int)stream.Position; } internal void Write(StreamHelper stream) { stream.WriteUshort(0x0208); // ROW stream.WriteUshort(0x0010); // record size stream.WriteUshort(row_index); stream.WriteUshort(first_col_index); stream.WriteUshort(last_col_index); stream.WriteUshort(row_height_bitfield); stream.SkipBytes(4); stream.WriteUint(row_options); last_position = (int)stream.Position; } internal BIFF8_Row() { } internal BIFF8_Row( ushort row_index, ushort first_col_index, ushort last_col_index, ushort row_height_bitfield, uint row_options) { this.row_index = row_index; this.first_col_index = first_col_index; this.last_col_index = last_col_index; this.row_height_bitfield = row_height_bitfield; this.row_options = row_options; } } internal class BIFF8_Sheet : ArrayList { // Sheet definiton in global section UInt32 absolute_position; byte sheet_state; byte sheet_type; string sheet_name; // Sheet index internal UInt32 first_row; internal UInt32 last_row; UInt32 def_col_width_ptr; UInt32[] db_cell_pos; // Dimension UInt32 first_used_row; UInt32 last_used_row; UInt16 first_used_column; UInt16 last_used_column; // Window 2 UInt16 window_options; UInt16 first_visible_row; UInt16 first_visible_col; UInt16 grid_line_color_idx; UInt16 page_break_magnification; UInt16 normal_magnification; // PAGESETUP UInt16 paper_size; UInt16 scaling_factor; UInt16 start_page_number; UInt16 fit_workshit_width; UInt16 fit_workshit_height; UInt16 page_options; UInt16 print_horizontal_dpi; UInt16 print_vertical_dpi; double header_margin; double footer_margin; UInt16 print_copies_count; /* +++++++++++++++++++++++++++++++++++++++++ */ internal UInt16 hcenter; internal UInt16 vcenter; internal double lmargin; internal double rmargin; internal double umargin; internal double bmargin; /* +++++++++++++++++++++++++++++++++++++++++ */ internal long sheet_position_index; /* +++++++++++++++++++++++++++++++++++++++++ */ internal ArrayList colinfo_list = new ArrayList(); internal ArrayList cell_ranges = new ArrayList(); internal ArrayList url_list = new ArrayList(); /* internal void Debug(StreamWriter debug, int idx) { debug.Write("\nSheet {0}", sheet_name); } */ /* ++++++++++++ Picture goes here ++++++++++++ */ internal ArrayList pictures_list = new ArrayList(); internal void Read_Globals(StreamHelper stream) { absolute_position = stream.ReadUint(); sheet_state = (byte)stream.ReadByte(); sheet_type = (byte)stream.ReadByte(); sheet_name = stream.ReadUnicodeString(true); } internal void Write_Globals(StreamHelper stream) { stream.WriteUshort(0x0085); // SHEET ushort payload_size = (ushort)(8 + sheet_name.Length * 2); stream.WriteUshort(payload_size); // Payload size this.sheet_position_index = stream.Position; stream.WriteUint(absolute_position); stream.WriteByte(sheet_state); stream.WriteByte(sheet_type); stream.WriteUnicodeString(sheet_name, true); } internal void Read_Index(StreamHelper stream) { stream.SkipBytes(4); // Not used in BIFF8 first_row = stream.ReadUint(); last_row = stream.ReadUint(); def_col_width_ptr = stream.ReadUint(); if (last_row == first_row) { return; } UInt32 nm = (last_row - first_row - 1) / 32 + 1; db_cell_pos = new UInt32[nm]; for (int i = 0; i < nm; i++) { db_cell_pos[i] = stream.ReadUint(); } } internal void Write_Index(StreamHelper stream) { stream.WriteUshort(0x020b); // INDEX if (last_row == first_row) { stream.WriteUshort(0x0010); // Payload size stream.SkipBytes(4); // Not used in BIFF8 stream.WriteUint(first_row); stream.WriteUint(last_row); stream.WriteUint(def_col_width_ptr); return; } UInt32 nm = (last_row - first_row - 1) / 32 + 1; stream.WriteUshort((ushort)(0x0010 + nm * sizeof(UInt32))); // Payload size stream.SkipBytes(4); // Not used in BIFF8 stream.WriteUint(first_row); stream.WriteUint(last_row); stream.WriteUint(def_col_width_ptr); if (last_row == first_row) { return; } db_cell_pos = new UInt32[nm]; for (int i = 0; i < nm; i++) { stream.WriteUint(db_cell_pos[i]); } } internal void Write_Margins(StreamHelper stream) { stream.WriteUshort(0x0026); // LMARGIN stream.WriteUshort(8); stream.WriteDouble(this.lmargin); stream.WriteUshort(0x0027); // RMARGIN stream.WriteUshort(8); stream.WriteDouble(this.rmargin); stream.WriteUshort(0x0028); // TMARGIN stream.WriteUshort(8); stream.WriteDouble(this.umargin); stream.WriteUshort(0x0029); // BMARGIN stream.WriteUshort(8); stream.WriteDouble(this.bmargin); } internal void Write_PageBreaks(StreamHelper stream, ExportMatrix matrix) { List breaks = new List(); for (int i = 0; i <= matrix.Height - 1; i++) if (matrix.YPosById(i) >= matrix.PageBreak(breaks.Count)) { breaks.Add(i); } if (breaks.Count != 0) { stream.WriteUshort(0x001b); // // HORIZONTALPAGEBREAKS: stream.WriteUshort((ushort)(2 + 6 * breaks.Count)); stream.WriteUshort((ushort)breaks.Count); for (int j = 0; j < breaks.Count; j++) { stream.WriteUshort((ushort)breaks[j]); stream.WriteUshort(0); stream.WriteUshort(16384); } } } internal void Read_PageSetup(StreamHelper stream) { paper_size = stream.ReadUshort(); scaling_factor = stream.ReadUshort(); start_page_number = stream.ReadUshort(); fit_workshit_width = stream.ReadUshort(); fit_workshit_height = stream.ReadUshort(); page_options = stream.ReadUshort(); print_horizontal_dpi = stream.ReadUshort(); print_vertical_dpi = stream.ReadUshort(); header_margin = stream.ReadDouble(); footer_margin = stream.ReadDouble(); print_copies_count = stream.ReadUshort(); } internal void Write_PageSetup(StreamHelper stream) { stream.WriteUshort(0x00a1); stream.WriteUshort(0x0022); stream.WriteUshort(paper_size); stream.WriteUshort(scaling_factor); stream.WriteUshort(start_page_number); stream.WriteUshort(fit_workshit_width); stream.WriteUshort(fit_workshit_height); stream.WriteUshort(page_options); stream.WriteUshort(print_horizontal_dpi); stream.WriteUshort(print_vertical_dpi); stream.WriteDouble(header_margin); stream.WriteDouble(footer_margin); stream.WriteUshort(print_copies_count); } internal void Read_Dimension(StreamHelper stream) { first_used_row = stream.ReadUint(); last_used_row = stream.ReadUint(); first_used_column = stream.ReadUshort(); last_used_column = stream.ReadUshort(); stream.SkipBytes(2); } internal void Write_Dimension(StreamHelper stream) { stream.WriteUshort(0x0200); stream.WriteUshort(0x000e); stream.WriteUint(first_used_row); //int val = 0; //// debug //last_used_row = (uint) val; //last_used_column = (ushort) val; stream.WriteUint(last_used_row); stream.WriteUshort(first_used_column); stream.WriteUshort(last_used_column); stream.SkipBytes(2); } internal void Read_Window2(StreamHelper stream) { window_options = stream.ReadUshort(); first_visible_row = stream.ReadUshort(); first_visible_col = stream.ReadUshort(); grid_line_color_idx = stream.ReadUshort(); stream.SkipBytes(2); page_break_magnification = stream.ReadUshort(); normal_magnification = stream.ReadUshort(); stream.SkipBytes(4); } internal void Write_Window2(StreamHelper stream) { stream.WriteUshort(0x023e); stream.WriteUshort(0x0012); stream.WriteUshort(window_options); stream.WriteUshort(first_visible_row); stream.WriteUshort(first_visible_col); stream.WriteUshort(grid_line_color_idx); stream.SkipBytes(2); stream.WriteUshort(page_break_magnification); stream.WriteUshort(normal_magnification); stream.SkipBytes(4); } internal void Read_Ranges(StreamHelper stream) { UInt16 range_count_follow = stream.ReadUshort(); for (int range_idx = 0; range_idx < range_count_follow; range_idx++) { FIFF8_CellRange single_range = new FIFF8_CellRange(); single_range.Read(stream); cell_ranges.Add(single_range); } } internal void Write_Ranges(StreamHelper stream) { int counter = cell_ranges.Count; int record_count = counter / 1027; if ((counter % 1027) != 0) record_count++; int item_count; int range_idx = 0; for (int i = 0; i < record_count; i++) { item_count = (counter <= 1027) ? counter : 1027; ushort payload_size = (ushort)(sizeof(UInt16) * (1 + item_count * 4)); stream.WriteUshort(0x00e5); stream.WriteUshort(payload_size); stream.WriteUshort((ushort)item_count); for (int j = 0; j < item_count; j++) { FIFF8_CellRange single_range = cell_ranges[range_idx++] as FIFF8_CellRange; single_range.Write(stream); counter--; } } } internal void Write_URLs(StreamHelper stream) { foreach (BIFF8_Hyperlink hlink in url_list) hlink.Write(stream); } internal void Write(Workbook stream, bool page_breaks, ExportMatrix matrix) { long store_index = stream.Position; stream.Position = sheet_position_index; stream.WriteUint((uint)store_index); stream.Position = store_index; stream.Write_BOF(0x0010); // Sheet // stream.Write_Index(this); if (page_breaks) this.Write_PageBreaks(stream, matrix); this.Write_Margins(stream); this.Write_PageSetup(stream); foreach (BIFF8_Colinfo column in this.colinfo_list) { column.Write(stream); } this.Write_Dimension(stream); if (this.Count != 0) { foreach (RowBlock row_block in this) { row_block.Write(stream); } } this.Write_Drawings(stream); this.Write_Window2(stream); this.Write_Ranges(stream); this.Write_URLs(stream); stream.Write_EOF(); // Sheet } private void Write_Drawings(StreamHelper stream) { bool is_drawing_group = true; uint total_size = 0; long current_stream_position; BIFF8_ExcelDrawing first_drawing = null; foreach (BIFF8_ExcelDrawing drawing in this.pictures_list) { total_size += drawing.Write(stream, is_drawing_group); if (is_drawing_group) { first_drawing = drawing; is_drawing_group = false; } drawing.Write_GraphicsObject(stream); } if (first_drawing != null) { current_stream_position = stream.Position; stream.Position = first_drawing.total_spgr_size_position; stream.WriteUint(total_size); stream.Position = first_drawing.total_dg_size_position; stream.WriteUint(total_size + 24); stream.Position = current_stream_position; } } internal BIFF8_Sheet() { } internal BIFF8_Sheet(string Name, bool hideGridLines) { this.sheet_name = Name; this.absolute_position = 0x3a7; scaling_factor = 0x0064; start_page_number = 0x0000; fit_workshit_width = 0x0001; fit_workshit_height = 0x0001; page_options = 0x0482; print_horizontal_dpi = 300; print_vertical_dpi = 300; header_margin = 0.0; footer_margin = 0.0; print_copies_count = 1; window_options = 0x06b6; first_visible_row = 0; first_visible_col = 0; grid_line_color_idx = 0x0040; page_break_magnification = 0; normal_magnification = 0; if (hideGridLines) window_options ^= 2; } internal RowBlock AddRow(BIFF8_Row row) { RowBlock row_block = null; do { if (this.Count != 0) { row_block = this[this.Count - 1] as RowBlock; if (row_block.Count < 32) break; } row_block = new RowBlock(); this.Add(row_block); } while (false); row_block.Add(row); return row_block; } } internal class Workbook : BIFF8_Stream { private static uint paletteSize = 0x40; private ArrayList font_list = new ArrayList(); private ArrayList format_list = new ArrayList(); private ArrayList xf_list = new ArrayList(); private ArrayList styles = new ArrayList(); private ArrayList sheet_list = new ArrayList(); private BIFF8_SharedStringTable shared_strings = new BIFF8_SharedStringTable(); private BIFF8_Window1 window1 = new BIFF8_Window1(); private RowBlock row_block; private Hashtable pic_list = new Hashtable(); internal bool hideGridLines; BIFF8_ExcelDrawing drawing; // palette int palUsed = 0; int[] palette = new int[paletteSize]; BIFF8_MSODrawingGroup drawing_group; // StreamWriter debug; private int ColorDiff(int color1, int color2) { color1 ^= color2; int res = 0; for (int i = 0; i < 4; i++) { res += color1 & 0xff; color1 = color1 >> 8; } return res; } private int NearestColor(int[] colors, int firstIndex, int color) { int res = firstIndex; int resDiff = ColorDiff(colors[res], color); for (int i = firstIndex + 1; i < colors.Length; i++) { int diff = ColorDiff(colors[i], color); if (diff < resDiff) { res = i; resDiff = diff; } } return res; } internal ushort AddColor(Color color, bool notFind) { return AddColor((color.A << 24) | (color.B << 16) | (color.G << 8) | color.R, notFind); } internal ushort AddColor(Color color) { return AddColor((color.A << 24) | (color.B << 16) | (color.G << 8) | color.R, false); } internal ushort AddColor(int color) { return AddColor(color, false); } internal ushort AddColor(int color, bool notFind) { color &= 0xffffff; int i; if (palUsed < 8) i = -1; else i = notFind ? palUsed : NearestColor(palette, 7, color); // If an exact match found, return the index. if (!notFind) { if (i >= 0 && palette[i] == color) return (ushort)i; // If no exact match found but palette is full, // return an index to the nearest color. if (i >= 0 && palUsed == paletteSize) return (ushort)i; } // If no exact match found and the palette is not full, // add the new color. // // alman's fix if (palUsed == paletteSize) return (ushort)NearestColor(palette, 7, color); palette[palUsed] = color; return (ushort)palUsed++; } private void Write_Palette() { WriteUshort(0x0092); // palette id WriteUshort(56 * 4 + 2); // payload size WriteUshort(56); // palette size WriteInts(palette, 8); // palette data } internal void Write_BOF(UInt16 type) { WriteUshort(0x0809); // BOF WriteUshort(0x0010); // Recod size WriteUshort(0x0600); // Version WriteUshort(type); // Type WriteUshort(0x1faa); // Build ID WriteUshort(0x07cd); // Build year WriteUint(0x000100c1); // History flags WriteUint(0x00000406); // Lovest version } internal void PrintUshortOption(UInt16 RecordID, UInt16 value) { WriteUshort(RecordID); // RecordID WriteUshort(0x0002); // Payload size WriteUshort(value); // Value } private void Write_1904() { WriteUshort(0x0022); // DATE mode WriteUshort(0x0002); // Payload size WriteUshort(0x0000); // False } internal void Write_EOF() { WriteUshort(0x000a); // END OF FILE WriteUshort(0x0000); // No payload for this command } public void Read(DirectoryEntry entry) { if (entry.type != DirectoryEntry.DirEntryType.UseStream) throw new Exception("Entry is not User stream"); //debug = new StreamWriter(@"C:\Users\alman\Desktop\Support\ReadBiffGen.txt"); int BytesCount = (int)entry.size; int debug_size; int count_of_row_records = 0; int Sheet_Index = -1; BIFF8_Sheet current_sheet = null; ArrayList cells = new ArrayList(); do { UInt16 RecordID = ReadUshort(); int RecordSize = ReadUshort(); BytesCount -= 4; debug_size = (int)this.Position; switch (RecordID) { case 0x0809: // BOF UInt16 version = ReadUshort(); UInt16 type = ReadUshort(); UInt16 build_id = ReadUshort(); UInt16 build_year = ReadUshort(); UInt32 history_flafs = ReadUint(); UInt32 lovest_ver = ReadUint(); if (type == 0x0010) { Sheet_Index++; current_sheet = this.sheet_list[Sheet_Index] as BIFF8_Sheet; } break; case 0x00e1: // INTERFACE UInt16 i_codepage = ReadUshort(); break; case 0x00c1: // MMS UInt16 mms = ReadUshort(); break; case 0x00e2: // INTERFACEEND break; case 0x005c: // WRITEACCESS SkipBytes(RecordSize); break; case 0x0042: UInt16 codepage = ReadUshort(); break; case 0x0161: // Double stream flag UInt16 double_stream = ReadUshort(); break; case 0x01c0: // ???? SkipBytes(RecordSize); break; case 0x13d: // RRD SkipBytes(RecordSize); break; case 0x009c: SkipBytes(RecordSize); break; case 0x0019: // WINDOWPOTECT UInt16 protect_val = ReadUshort(); break; case 0x0012: // PROTCT UInt16 protect_modify = ReadUshort(); break; case 0x0013: // PASSWORD UInt16 pass_hash = ReadUshort(); break; case 0x1af: // PROTREV UInt16 prot_rev = ReadUshort(); break; case 0x01bc: // PROTREVPASS UInt16 prot_rev_pass = ReadUshort(); break; case 0x003d: // WINDOW1 window1.Read(this); break; case 0x0040: // BACKUP UInt16 create_backup = ReadUshort(); break; case 0x008d: // HIDEOBJ UInt16 hide_object = ReadUshort(); break; case 0x0022: // DATAMODE UInt16 data_mode = ReadUshort(); break; case 0x000e: // PRECISION UInt16 precision = ReadUshort(); break; case 0x01b7: // REFRESHALL UInt16 refreshall = ReadUshort(); break; case 0x00da: // BOOKBOOL is "save external values?" UInt16 book_bool = ReadUshort(); break; case 0x0031: // FONT BIFF8_Font font = new BIFF8_Font("", 0, 0); font.Read(this); //#if DEBUG // font.Debug(debug, font_list.Count); //#endif font_list.Add(font); break; case 0x041e: // Format UInt16 format_idx = ReadUshort(); string format_str = ReadUnicodeString(false); BIFF8_Format format = new BIFF8_Format(format_idx, format_str); //#if DEBUG // format.Debug(debug, format_list.Count); //#endif format_list.Add(format); break; case 0x00e0: // XF extended format BIFF8_ExtendedFormat xf_format = new BIFF8_ExtendedFormat(); xf_format.Read(this); //#if DEBUG // xf_format.Debug(debug, this.xf_list.Count); //#endif this.xf_list.Add(xf_format); break; case 0x87c: // Something unknown case 0x87d: // Something unknown SkipBytes(RecordSize); break; case 0x0293: // STYLE BIFF8_Style style = new BIFF8_Style(); style.Read(this); //#if DEBUG // style.Debug(debug, this.styles.Count); //#endif this.styles.Add(style); break; case 0x0892: // Style payload SkipBytes(RecordSize); break; case 0x088e: // ??????? SkipBytes(RecordSize); break; case 0x0160: // USESELFS UInt16 natural_lang_formulas = ReadUshort(); break; case 0x0085: // SHEET BIFF8_Sheet sheet = new BIFF8_Sheet(); sheet.Read_Globals(this); //#if DEBUG // sheet.Debug(debug, this.sheet_list.Count); //#endif this.sheet_list.Add(sheet); break; case 0x089a: case 0x08a3: SkipBytes(RecordSize); break; case 0x008c: UInt16 interface_language = ReadUshort(); UInt16 system_region = ReadUshort(); break; case 0x01c1: SkipBytes(RecordSize); break; case 0x00eb: // MSODRAWINGGROUP drawing_group = new BIFF8_MSODrawingGroup(); int tmp = drawing_group.Read(this, RecordSize); RecordSize = tmp; break; case 0x00fc: // Shared string table int tmp2 = shared_strings.Read(this, RecordSize); RecordSize = tmp2; break; case 0x00ff: // Extended SST ushort strings_in_bucket = ReadUshort(); int payload_size = RecordSize - sizeof(ushort); while (payload_size > 0) { uint stream_pos = ReadUint(); ushort sst_offset = ReadUshort(); SkipBytes(2); payload_size -= 8; } break; case 0x0863: // Extra Book Info SkipBytes(RecordSize); break; case 0x0896: // Theme case 0x089B: // COMPRESSPICTURES case 0x088C: // Compatibility Checker 12 SkipBytes(RecordSize); break; case 0x000a: // EOF break; // Sheet properties here case 0x020b: // INDEX current_sheet.Read_Index(this); break; case 0x000d: //CALCMODE UInt16 calc_mode = ReadUshort(); break; case 0x000c: // CALCCOUNT UInt16 calc_count = ReadUshort(); break; case 0x000f: // REFMODE UInt16 ref_mode = ReadUshort(); break; case 0x0011: // ITERATION UInt16 iteration = ReadUshort(); break; case 0x0010: // DELTA SkipBytes(RecordSize); break; case 0x005f: // SAVERECALC UInt16 save_recalc = ReadUshort(); break; case 0x002a: // PRINTHEADERS UInt16 print_headers = ReadUshort(); break; case 0x002b: // PRINTGRIDLINES UInt16 print_grid = ReadUshort(); break; case 0x0082: // GRIDSET (?? Stupid option) UInt16 grid_set = ReadUshort(); break; case 0x0080: // GUTS UInt16 outlines_width = ReadUshort(); UInt16 outlines_height = ReadUshort(); UInt16 visible_row_levels = ReadUshort(); UInt16 visible_column_Levels = ReadUshort(); break; case 0x0225: // DEFAULTROWHEIGHT UInt16 def_row_options = ReadUshort(); UInt16 default_row_height = ReadUshort(); break; case 0x0081: // SHEETPR (Sheet properties) UInt16 sheet_flags = ReadUshort(); break; case 0x001b: // HORIZONTALPAGEBREAKS: ushort cbrk = ReadUshort(); for (int j = 0; j < cbrk; j++) { ushort row_of_break = ReadUshort(); ushort beg_col = ReadUshort(); ushort end_col = ReadUshort(); } break; case 0x0014: // SHEET HEADER string sheet_header = ""; if (RecordSize != 0) { sheet_header = ReadUnicodeString(false); } break; case 0x0015: // SHET FOOTER string sheet_footer = ""; if (RecordSize != 0) { sheet_footer = ReadUnicodeString(false); } break; case 0x0083: // HCENTER current_sheet.hcenter = ReadUshort(); break; case 0x0084: // VCENTER current_sheet.vcenter = ReadUshort(); break; case 0x0026: // LMARGIN current_sheet.lmargin = ReadDouble(); break; case 0x0027: // RMARGIN current_sheet.rmargin = ReadDouble(); break; case 0x0028: // UP_MARGIN current_sheet.umargin = ReadDouble(); break; case 0x0029: // BOTTOM_MARGIN current_sheet.bmargin = ReadDouble(); break; case 0x00a1: // PAGESETUP current_sheet.Read_PageSetup(this); break; case 0x089c: // ??? SkipBytes(RecordSize); break; case 0x004d: // internal settings for current printer SkipBytes(RecordSize); break; case 0x0055: // DEFCOLWIDTH UInt16 default_column_width = ReadUshort(); break; case 0x007d: // COLINFO BIFF8_Colinfo colinfo = new BIFF8_Colinfo(); colinfo.Read(this); //#if DEBUG // colinfo.Debug(debug, current_sheet.colinfo_list.Count); //#endif current_sheet.colinfo_list.Add(colinfo); break; case 0x0200: // DIMENSION current_sheet.Read_Dimension(this); count_of_row_records = 0; break; case 0x0208: // ROW BIFF8_Row row = new BIFF8_Row(); row.Read(this); //#if DEBUG // row.Debug(debug, count_of_row_records); //#endif row_block = current_sheet.AddRow(row); count_of_row_records++; break; case 0x00fd: // LABELSST BIFF8_LabelSST label = new BIFF8_LabelSST(); label.Read(this); //#if DEBUG // label.Debug(debug, row_block.cells.Count); //#endif row_block.cells.Add(label); break; case 0x0203: // NUMBER: Cell Value, Floating-Point Number BIFF8_FloatNumber float_cell = new BIFF8_FloatNumber(); float_cell.Read(this); row_block.cells.Add(float_cell); break; case 0x0201: // BLANK BIFF8_Blank blank = new BIFF8_Blank(); blank.Read(this); //#if DEBUG // blank.Debug(debug, row_block.cells.Count); //#endif row_block.cells.Add(blank); break; case 0x027e: // Number BIFF8_Number number = new BIFF8_Number(); number.Read(this); //#if DEBUG // number.Debug(debug, row_block.cells.Count); //#endif row_block.cells.Add(number); break; case 0x00be: // MULBLANK BIFF8_MulBlank mul_blank = new BIFF8_MulBlank((ushort)RecordSize); mul_blank.Read(this); //#if DEBUG // mul_blank.Debug(debug, row_block.cells.Count); //#endif row_block.cells.Add(mul_blank); break; case 0x00d7: // DBCELL row_block = current_sheet[current_sheet.Count - 1] as RowBlock; row_block.Read(this); break; case 0x00ec: // DRAWING drawing = new BIFF8_ExcelDrawing(); drawing.Read(this, (UInt32)RecordSize); current_sheet.pictures_list.Add(drawing); break; case 0x005d: // OBJ: Describes a Graphic Object drawing.Read_GraphicsObject(this, (UInt32)RecordSize); break; case 0x023e: // WINDOW2 current_sheet.Read_Window2(this); break; case 0x088B: case 0x001D: SkipBytes(RecordSize); break; case 0x00e5: // CELL RANGE current_sheet.Read_Ranges(this); break; case 0x0867: SkipBytes(RecordSize); break; default: Console.WriteLine( string.Format("Found unparsed BIFF record: {0:X04} {1} bytes", new object[] { RecordID, RecordSize }) ); SkipBytes(RecordSize); break; } debug_size = (int)this.Position - debug_size; if (debug_size != RecordSize) { string.Format("Catch it"); throw new Exception("Item size error"); } BytesCount -= RecordSize; } while (BytesCount > 0); //#if DEBUG // shared_strings.Debug(debug); //#endif // debug.Close(); } internal void Prepare(ExportMatrix export_matrix, bool page_breaks, string name_postfix) { const float MargDiv = 25.4F; AddColor(0x000000); // black AddColor(0xFFFFFF); // white AddColor(0x0000FF); // red AddColor(0x00FF00); // green AddColor(0xFF0000); // blue AddColor(0x00FFFF); // yellow AddColor(0xFF00FF); // magenta AddColor(0xFFFF00); // cyan BIFF8_Blank blank_cell; BIFF8_ExtendedFormat biff_style_xf; BIFF8_Font biff_font; BIFF8_Style biff_style; biff_style_xf = new BIFF8_ExtendedFormat(); for (int i = 0; i < 15; i++) xf_list.Add(biff_style_xf); ushort empty_cell_style = (ushort)xf_list.Count; // empty cell style biff_style_xf = new BIFF8_ExtendedFormat(); biff_style_xf.xf_type = 0x1; xf_list.Add(biff_style_xf); biff_style = new BIFF8_Style(); styles.Add(biff_style); for (int i = 0; i < 21; i++) { biff_font = new BIFF8_Font("Arial", 220, 12); font_list.Add(biff_font); } int start_font_idx = font_list.Count + 1; ushort default_styles_count = (ushort)xf_list.Count; for (ushort i = 0; i < export_matrix.StylesCount; i++) { ExportIEMStyle EStyle = export_matrix.StyleById(i); biff_font = new BIFF8_Font(EStyle, AddColor(EStyle.TextColor, true)); font_list.Add(biff_font); ushort idx = (ushort)(i + default_styles_count); // 164 - 382 indices for users formats BIFF8_ExtendedFormat biff_xf = new BIFF8_ExtendedFormat(false, (ushort)(i + start_font_idx), EStyle, this, 164 + idx); xf_list.Add(biff_xf); if (biff_xf.format_index > 163) format_list.Add(new BIFF8_Format(biff_xf.format_index, ExportUtils.GetExcelFormatSpecifier(EStyle.Format))); biff_style = new BIFF8_Style((ushort)idx, EStyle); styles.Add(biff_style); } string name = export_matrix.Report.PreparedPages.GetPage(0).Name + name_postfix; BIFF8_Sheet sheet = new BIFF8_Sheet(name, hideGridLines); this.sheet_list.Add(sheet); for (ushort x = 0; x < export_matrix.Width - 1; x++) { ushort width = (ushort)(34 * (export_matrix.XPosById(x + 1) - export_matrix.XPosById(x))); sheet.colinfo_list.Add(new BIFF8_Colinfo(x, width, empty_cell_style)); } for (ushort y = 0; y < export_matrix.Height - 1; y++) { ushort row_height = (ushort)(14 * (export_matrix.YPosById(y + 1) - export_matrix.YPosById(y))); BIFF8_Row row = new BIFF8_Row(y, 0, (ushort)export_matrix.Width, row_height, 0x00000140); sheet.AddRow(row); ushort StyleIndex = 0; for (ushort x = 0; x < export_matrix.Width - 1; x++) { string val = "$" + Convert.ToChar('A' + x) + "$" + (y + 1).ToString(); StyleIndex = 0; int i = export_matrix.Cell(x, y); if (i != -1) { int fx, fy, dx, dy; export_matrix.ObjectPos(i, out fx, out fy, out dx, out dy); ExportIEMObject Obj = export_matrix.ObjectById(i); StyleIndex = (ushort)(Obj.StyleIndex + default_styles_count); if (Obj.Counter < dy) { if (Obj.Counter == 0) { BIFF8_CellData cell; if (Obj.IsDateTime) { DateTime dt = (DateTime)Obj.Value; cell = new BIFF8_Number(y, x, StyleIndex, dt); } else if (Obj.IsNumeric && Obj.Value != null) { Decimal num = (Decimal)Obj.Value; cell = new BIFF8_FloatNumber(y, x, StyleIndex, num); } else { // val = ExportUtils.XmlString(Obj.Text, Obj.HtmlTags); val = ""; foreach (char ch in Obj.Text) if (ch != 0xd) val += ch; cell = new BIFF8_LabelSST(y, x, StyleIndex, shared_strings.Count); shared_strings.Add(val); } row.Add(cell); if (Obj.URL != null && Obj.URL.Length != 0) { BIFF8_Hyperlink link = new BIFF8_Hyperlink(Obj.URL); sheet.url_list.Add(link); } } else { blank_cell = new BIFF8_Blank((ushort)y, (ushort)x, StyleIndex); row.Add(blank_cell); } if (!Obj.IsText) // Picture { if (Obj.Width > 0 && Obj.Counter == 0) { BIFF8_MSODrawingRecord rec; if (drawing_group == null) drawing_group = new BIFF8_MSODrawingGroup(); int pic_index; if (!this.pic_list.ContainsKey(Obj.Hash)) { rec = new BIFF8_MSODrawingRecord(); pic_index = drawing_group.Count; rec.LoadPicture(Obj, pic_index); drawing_group.Add(rec); this.pic_list.Add(Obj.Hash, pic_index); } else { pic_index = (int)this.pic_list[Obj.Hash]; rec = drawing_group[pic_index] as BIFF8_MSODrawingRecord; rec.AddReference(); } drawing = new BIFF8_ExcelDrawing(); drawing.AddPicureToSheet(Obj, pic_index, fx, fy, dx, dy); sheet.pictures_list.Add(drawing); } } // Add multiple blanks for merged cells BIFF8_MulBlank cells; if (dx > 1) { if (Obj.Counter == 0 && Obj.IsText) cells = new BIFF8_MulBlank((ushort)y, (ushort)(x + 1), (ushort)(x + dx - 1), StyleIndex); else cells = new BIFF8_MulBlank((ushort)y, (ushort)(x), (ushort)(x + dx - 1), StyleIndex); row.Add(cells); x += (ushort)(dx - 1); } Obj.Counter++; if ((Obj.Counter == dy) && (dx > 1 || dy > 1)) { FIFF8_CellRange single_range = new FIFF8_CellRange((ushort)fy, (ushort)(fy + dy - 1), (ushort)fx, (ushort)(fx + dx - 1)); sheet.cell_ranges.Add(single_range); } } } else { BIFF8_CellData cell = new BIFF8_Blank(y, x, StyleIndex); row.Add(cell); } } } base.SetLength(0); this.Write_BOF(0x0005); // Workbook globals this.window1.Write(this); this.Write_1904(); // Skip many records at this point foreach (BIFF8_Font font in this.font_list) font.Write(this); foreach (BIFF8_Format format in this.format_list) format.Write(this); foreach (BIFF8_ExtendedFormat xf in this.xf_list) xf.Write(this); // Skip many records at this point foreach (BIFF8_Style style in this.styles) style.Write(this); this.Write_Palette(); // PALETTE // Skip many records at this point foreach (BIFF8_Sheet sheetItem in this.sheet_list) { sheetItem.Write_Globals(this); } // Skip some records at this point if (drawing_group != null) drawing_group.Write(this); shared_strings.Write(this); // Skip some records at this point Write_EOF(); // Write sheet to stream foreach (BIFF8_Sheet sheetItem in this.sheet_list) { sheet.lmargin = export_matrix.PageLMargin(0) / MargDiv; sheet.rmargin = export_matrix.PageRMargin(0) / MargDiv; sheet.umargin = export_matrix.PageTMargin(0) / MargDiv; sheet.bmargin = export_matrix.PageBMargin(0) / MargDiv; sheetItem.Write(this, page_breaks, export_matrix); } int eof = -1; unchecked { this.streamDirEntry.bOF = (uint)eof; } this.streamDirEntry.size = (uint)this.Length; this.Position = 0; if (drawing_group != null) { drawing_group.Clear(); drawing_group = null; } } public Workbook(CompoundDocumentHeader document_header, DirectoryEntry dir) : base(document_header, dir) { } internal void Write(FileStream f) { DirectoryEntry dir = base.streamDirEntry; } } /// /// Excel 2003 export class /// public partial class Excel2003Document : ExportBase { ExportMatrix matrix; int page_num; bool split_pages = false; CompoundDocumentHeader hdr; DirectoryStream root_dir; Workbook workbook; OLE_Stream summary_info; OLE_Stream doc_summary_info; private bool wysiwyg; private bool pageBreaks; private bool hideGridLines; private bool printOptimized; /// /// Gets or sets a value that determines whether the wysiwyg mode should be used /// for better results. /// public bool Wysiwyg { get { return wysiwyg; } set { wysiwyg = value; } } /// /// Gets or sets a value that determines whether to insert page breaks in the output file or not. /// public bool PageBreaks { get { return pageBreaks; } set { pageBreaks = value; } } /// /// Gets or sets a value that determines whether to hide gridlines. /// public bool HideGridLines { get { return hideGridLines; } set { hideGridLines = value; } } /// /// Enables or disables optimization of images for printing. /// public bool PrintOptimized { get { return printOptimized; } set { printOptimized = value; } } /// /// Read and parse Excel document /// public void Read(string FileName) { FileStream f = File.Open(FileName, System.IO.FileMode.Open); hdr = new CompoundDocumentHeader(f); hdr.Read(); root_dir = new DirectoryStream(hdr); root_dir.Read(hdr.dir, hdr); /* #if _DEBUG Console.WriteLine(string.Format("{0,-35} {1,-12} {2,8} {3,5} {4,4} {5,4} {6,4}", new object[] { "Name", "Type", "Size", "BOF", "Root", "Left", "Rght"})); #endif */ foreach (DirectoryEntry entry in root_dir) { if (entry.type == DirectoryEntry.DirEntryType.Empty) continue; /* #if _DEBUG Console.WriteLine(string.Format("{0,-35} {1,-12} {2,8} {3,5} {4,4} {5,4} {6,4}", new object[] { entry.entry_name, entry.type, entry.Size, entry.BOF, entry.RootDirID, entry.LeftChildDirID, entry.RightChildDirID })); #endif */ switch (entry.entry_name) { case "Root Entry": hdr.ReadShortStreamContainer(entry); break; case "Workbook": workbook = new Workbook(hdr, entry); workbook.Read(entry); break; case "SummaryInformation": summary_info = new OLE_Stream(hdr, entry); //summary_info.Read(); break; case "DocumentSummaryInformation": doc_summary_info = new OLE_Stream(hdr, entry); //doc_summary_info.Read(); break; case "CompObj": continue; default: throw new Exception("Unknown stream"); } } f.Close(); } private void Prepare(string name_postfix) { hdr.Reset(); root_dir.Reset(); workbook.Prepare(matrix, pageBreaks, name_postfix); workbook.Write(); summary_info.Write(); doc_summary_info.Write(); DirectoryEntry root = root_dir.Add("Root Entry"); root_dir.Add("Workbook", workbook, -1, -1); root_dir.Add("SummaryInformation", summary_info, 1, -1); root_dir.Add("DocumentSummaryInformation", doc_summary_info, 2, -1); root_dir.Write(hdr.dir, hdr); hdr.Write(); } internal void Write(string FileName) { this.Prepare(""); FileStream f = File.Open(FileName, System.IO.FileMode.Create, FileAccess.ReadWrite); hdr.FinalWriteToStream(f); f.Close(); } /// public Excel2003Document() { pageBreaks = true; wysiwyg = true; hideGridLines = false; printOptimized = false; } internal void Create() { // These lines are useful for debug XLS file // this.Read(@"C:\Users\alman\Desktop\Support\Simple List_back.xls"); // this.Read(@"C:\Users\alman\Desktop\Support\Simple List.xls"); //this.Read(@"C:\Users\alman\Desktop\Support\Groups.xls"); // this.Read(@"C:\Users\alman\Desktop\Support\Single.xls"); // this.Read(@"C:\Users\alman\Desktop\Support\crlf_fix.xls"); // this.Read(@"C:\Users\alman\Desktop\Support\Huge.xls"); hdr = new CompoundDocumentHeader(); root_dir = new DirectoryStream(hdr); DirectoryEntry workbook_entry = new DirectoryEntry("Workbook", DirectoryEntry.DirEntryType.UseStream); workbook = new Workbook(hdr, workbook_entry); workbook.hideGridLines = hideGridLines; DirectoryEntry summary_entry = new DirectoryEntry("SummaryInformation", DirectoryEntry.DirEntryType.UseStream); summary_info = new OLE_Stream(hdr, summary_entry); DirectoryEntry doc_summary_entry = new DirectoryEntry("DocumentSummaryInformation", DirectoryEntry.DirEntryType.UseStream); doc_summary_info = new OLE_Stream(hdr, doc_summary_entry); } #region Protected Methods private void initalize_matix() { matrix = new ExportMatrix(); if (wysiwyg) matrix.Inaccuracy = 0.5f; else matrix.Inaccuracy = 10; matrix.PlainRich = true; matrix.AreaFill = false; // true; // matrix.CropAreaFill = true; matrix.Report = Report; matrix.Images = true; matrix.WrapText = false; matrix.FullTrust = false; matrix.MaxCellHeight = 409 * 1; matrix.PrintOptimized = PrintOptimized; } /// protected override void Start() { base.Start(); page_num = 1; this.Create(); if (!split_pages) { initalize_matix(); } } /// protected override void ExportPageBegin(ReportPage page) { base.ExportPageBegin(page); if (split_pages) { initalize_matix(); } matrix.AddPageBegin(page); } /// protected override void ExportBand(BandBase band) { base.ExportBand(band); //if (sheets.ContainsKey(band.Page.Name)) //{ // sh = sheets[band.Page.Name] as OoXMLSheet; // sh.Matrix.AddBand(band); //} //else { matrix.AddBand(band, this); } } /// protected override void ExportPageEnd(ReportPage page) { //if (sheets.ContainsKey(page.Name)) //{ // sh = sheets[page.Name] as OoXMLSheet; // sh.Matrix.AddPageEnd(page); //} //else //{ matrix.AddPageEnd(page); // page_name = page.Name; // Export(true); // sh = new OoXMLSheet(matrix, page.Name, sheets.Count + 1); // sheets[page.Name] = sh; // FWorkBook.AddSheet(sh); //} if (split_pages) { matrix.Prepare(); this.Prepare("_" + page_num.ToString()); page_num++; } } /// protected override void Finish() { if (!split_pages) { matrix.Prepare(); this.Prepare(""); } hdr.FinalWriteToStream(Stream); } /// protected override string GetFileFilter() { return new MyRes("FileFilters").Get("XlsFile"); } /// public override void Serialize(FRWriter writer) { base.Serialize(writer); writer.WriteBool("Wysiwyg", Wysiwyg); writer.WriteBool("PageBreaks", PageBreaks); writer.WriteBool("HideGridLines", HideGridLines); writer.WriteBool("PrintOptimized", PrintOptimized); } #endregion } }