powered by simpleCommunicator - 2.0.54     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / сложная шапка в excel через Open XML SDK
8 сообщений из 8, страница 1 из 1
сложная шапка в excel через Open XML SDK
    #38952764
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
киньте примерчик,
...
Рейтинг: 0 / 0
сложная шапка в excel через Open XML SDK
    #38953185
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степикиньте примерчик,Создать книгу-шаблон со сложной шапкой в Excel. Заполнять готовый шаблон?
...
Рейтинг: 0 / 0
сложная шапка в excel через Open XML SDK
    #38953198
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К,
все таблицы формируются динамический, темплейты тут не пролезут
...
Рейтинг: 0 / 0
сложная шапка в excel через Open XML SDK
    #38953200
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OpenXML мне показался очень неудобным, хотя я сделал с его помощью всё что мне требовалось. Для упрощения жизни пишется набор хелперов вроде:
Костыли
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
 public static class OpenXmlExcelHelper
    {
        #region Append To Stylesheet

        public static uint AppendCellFormat(this SpreadsheetDocument document, CellFormat cellFormat)
        {
            var stylesheet = document.WorkbookPart.WorkbookStylesPart.Stylesheet;

            if (stylesheet.CellFormats == null)
                stylesheet.CellFormats = new CellFormats();

            stylesheet.CellFormats.Append(cellFormat);
            return (uint)stylesheet.CellFormats.FirstIndex(v => cellFormat == v);
        }

        public static uint AppendFont(this SpreadsheetDocument document, Font font)
        {
            var stylesheet = document.WorkbookPart.WorkbookStylesPart.Stylesheet;

            if (stylesheet.Fonts == null)
                stylesheet.Fonts = new Fonts();

            stylesheet.Fonts.Append(font);
            return (uint)stylesheet.Fonts.FirstIndex(v => font == v);
        }

        public static uint AppendBorder(this SpreadsheetDocument document, Border border)
        {
            var stylesheet = document.WorkbookPart.WorkbookStylesPart.Stylesheet;

            if (stylesheet.Borders == null)
                stylesheet.Borders = new Borders();

            stylesheet.Borders.Append(border);
            return (uint)stylesheet.Borders.FirstIndex(v => border == v);
        }        

        public static uint AppendNumberingFormat(this SpreadsheetDocument document, NumberingFormat numberingFormat)
        {
            var stylesheet = document.WorkbookPart.WorkbookStylesPart.Stylesheet;

            if (stylesheet.NumberingFormats == null)
                stylesheet.NumberingFormats = new NumberingFormats();

            stylesheet.NumberingFormats.Append(numberingFormat);

            if (numberingFormat.NumberFormatId == null)
            {
                var id = (uint)(stylesheet.NumberingFormats.FirstIndex(v => numberingFormat == v) + MinCustomNumberFormatId);
                numberingFormat.NumberFormatId = id;
            }

            return numberingFormat.NumberFormatId;
        }

        #endregion

        #region Stylesheet Query

        public static Font GetDefaultFont(this SpreadsheetDocument document)
        {
            var stylesheet = document.WorkbookPart.WorkbookStylesPart.Stylesheet;
            return (Font)stylesheet.Fonts.First();
        }

        public static Font GetCellFont(this SpreadsheetDocument document, Cell cell)
        {
            var stylesheet = document.WorkbookPart.WorkbookStylesPart.Stylesheet;
            var cellFormat = document.GetCellFormat(cell);

            if (cellFormat.ApplyFont != null && cellFormat.ApplyFont && cellFormat.FontId != null)
                return (Font)stylesheet.Fonts.ElementAt((int)(uint)cellFormat.FontId);

            return document.GetDefaultFont();
        }

        public static CellFormat GetDefaultCellFormat(this SpreadsheetDocument document)
        {
            var stylesheet = document.WorkbookPart.WorkbookStylesPart.Stylesheet;
            return (CellFormat)stylesheet.CellFormats.First();
        }

        public static CellFormat GetCellFormat(this SpreadsheetDocument document, Cell cell)
        {
            var stylesheet = document.WorkbookPart.WorkbookStylesPart.Stylesheet;

            if (cell.StyleIndex != null)
                return (CellFormat)stylesheet.CellFormats.ElementAt((int)(uint)cell.StyleIndex);

            return document.GetDefaultCellFormat();
        }

        public static string GetCellNumberFormatCode(this SpreadsheetDocument document, Cell cell)
        {
            var stylesheet = document.WorkbookPart.WorkbookStylesPart.Stylesheet;

            if (cell.DataType != CellValues.Number)
                return null;

            var cellStyle = document.GetCellFormat(cell);

            if (cellStyle.ApplyNumberFormat == null || cellStyle.ApplyNumberFormat == false || cellStyle.NumberFormatId == null)
                return null;

            string defaultNumberFormatCode;

            if (DefaultNumberFormats.TryGetValue(cellStyle.NumberFormatId, out defaultNumberFormatCode))
                return defaultNumberFormatCode;

            var numberFormat = stylesheet.NumberingFormats
                .Cast<NumberingFormat>()
                .FirstOrDefault(v => (uint)v.NumberFormatId == (uint)cellStyle.NumberFormatId);

            if (numberFormat != null && numberFormat.FormatCode != null)
                return numberFormat.FormatCode;

            return null;
        }

        #endregion

        #region Default Number Formats

        // http://closedxml.codeplex.com/wikipage?title=NumberFormatId%20Lookup%20Table

        const int MinCustomNumberFormatId = 1000;

        static readonly Dictionary<uint, string> DefaultNumberFormats =
            new[] 
            {
                // System.Tuple.Create(0, General),
                System.Tuple.Create(1, "0"),
                System.Tuple.Create(2, "0.00"),
                System.Tuple.Create(3, "#,##0"),
                System.Tuple.Create(4, "#,##0.00"),
                System.Tuple.Create(9, "0%"),
                System.Tuple.Create(10, "0.00%"),
                System.Tuple.Create(11, "0.00E+00"),
                System.Tuple.Create(12, "# ?/?"),
                System.Tuple.Create(13, "# ??/??"),
                System.Tuple.Create(14, "d/m/yyyy"),
                System.Tuple.Create(15, "d-mmm-yy"),
                System.Tuple.Create(16, "d-mmm"),
                System.Tuple.Create(17, "mmm-yy"),
                System.Tuple.Create(18, "h:mm tt"),
                System.Tuple.Create(19, "h:mm:ss tt"),
                System.Tuple.Create(20, "H:mm"),
                System.Tuple.Create(21, "H:mm:ss"),
                System.Tuple.Create(22, "m/d/yyyy H:mm"),
                System.Tuple.Create(37, "#,##0 ;(#,##0)"),
                System.Tuple.Create(38, "#,##0 ;[Red](#,##0)"),
                System.Tuple.Create(39, "#,##0.00;(#,##0.00)"),
                System.Tuple.Create(40, "#,##0.00;[Red](#,##0.00)"),
                System.Tuple.Create(45, "mm:ss"),
                System.Tuple.Create(46, "[h]:mm:ss"),
                System.Tuple.Create(47, "mmss.0"),
                System.Tuple.Create(48, "##0.0E+0"),
                System.Tuple.Create(49, "@")
            }
            .ToDictionary(v => (uint)v.Item1, v => v.Item2);

        #endregion
    }


Дальше, глаза бояться, руки делают:
Что-то вроде
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
namespace SspMain
{
    public class OpenXmlExcelTableExporter : IExcelTableExporter
    {
        #region IExcelTableExporter Members

        ExcelTableExporterModel Model;

        IEnumerable Data;

        SpreadsheetDocument Document;

        Worksheet Worksheet;

        SheetData SheetData;

        OpenXmlExcelTextMeasure TextMeasure;

        public Stream Execute(ExcelTableExporterModel model, IEnumerable data)
        {
            Model = model;
            Data = data;

            ResetColumnWidths();

            var result = TempFileHelper.OpenTempFile();
            try
            {
                var template = Resources.EmptyTemplate;
                result.Write(template, 0, template.Length);
                result.Seek(0, SeekOrigin.Begin);

                using (Document = SpreadsheetDocument.Open(result, true))
                using (TextMeasure = new OpenXmlExcelTextMeasure(Document))
                {
                    Worksheet = Document.WorkbookPart.WorksheetParts.First().Worksheet;
                    SheetData = Worksheet.GetFirstChild<SheetData>();

                    WriteStyles();
                    WriteDocumentHeader();
                    WriteTableHeader();
                    WriteTableData();
                    WriteTableColumns();
                }

                result.Seek(0, SeekOrigin.Begin);
                return result;
            }
            catch
            {
                result.Dispose();
                throw;
            }
        }

        #endregion

        #region Styles

        uint DocumentHeaderCellFormat;

        uint TableHeaderCellFormat;

        uint TableCommonCellFormat;

        uint TableDateCellFormat;

        uint TableDateTimeCellFormat;

        void WriteStyles()
        {
            DocumentHeaderCellFormat = Document.AppendCellFormat(new CellFormat
            {
                ApplyFont = true,
                FontId = Document.AppendFont(new Font
                {
                    FontSize = new FontSize { Val = 16 },
                    Bold = new Bold()
                })
            });

            var tableBorder = Document.AppendBorder(new Border
            {
                LeftBorder = new LeftBorder { Style = BorderStyleValues.Thin },
                RightBorder = new RightBorder { Style = BorderStyleValues.Thin },
                TopBorder = new TopBorder { Style = BorderStyleValues.Thin },
                BottomBorder = new BottomBorder { Style = BorderStyleValues.Thin }
            });

            TableHeaderCellFormat = Document.AppendCellFormat(new CellFormat
            {
                ApplyFont = true,
                FontId = Document.AppendFont(new Font { Bold = new Bold() }),
                ApplyBorder = true,
                BorderId = tableBorder
            });

            TableCommonCellFormat = Document.AppendCellFormat(new CellFormat
            {
                ApplyBorder = true,
                BorderId = tableBorder
            });

            TableDateCellFormat = Document.AppendCellFormat(new CellFormat
            {
                ApplyBorder = true,
                BorderId = tableBorder,
                ApplyNumberFormat = true,
                NumberFormatId = Document.AppendNumberingFormat(new NumberingFormat
                {
                    FormatCode = "dd/mm/yyyy"
                })
            });

            TableDateTimeCellFormat = Document.AppendCellFormat(new CellFormat
            {
                ApplyBorder = true,
                BorderId = tableBorder,
                ApplyNumberFormat = true,
                NumberFormatId = Document.AppendNumberingFormat(new NumberingFormat
                {
                    FormatCode = "dd/mm/yyyy hh:mm"
                })
            });
        }

        #endregion

        #region Cells

        void WriteDocumentHeader()
        {
            var row = new Row();

            row.Append(new Cell
            {
                StyleIndex = DocumentHeaderCellFormat,
                DataType = CellValues.String,
                CellValue = new CellValue(Model.Name)
            });

            SheetData.Append(row);
            SheetData.Append(new Row());
        }

        void WriteTableHeader()
        {
            var row = new Row();
            var columnIndex = 0;

            foreach (var column in Model.Columns)
            {
                var cell = new Cell
                {
                    StyleIndex = TableHeaderCellFormat,
                    DataType = CellValues.String,
                    CellValue = new CellValue(column.Header)
                };

                row.Append(cell);

                if (column.Width.HasValue == false)
                {
                    var width = TextMeasure.GetCellWidth(cell);
                    SetColumnWidth(columnIndex, width);
                }

                columnIndex++;
            }

            SheetData.Append(row);
        }

        void WriteTableData()
        {
            PropertyPathInfo[] valueAccessors = null;

            foreach (var dataItem in Data)
            {
                if (valueAccessors == null)
                    valueAccessors = Model.Columns
                        .Select(column => PropertyPathFactory.Create(dataItem.GetType(), column.PropertyName))
                        .ToArray();

                var row = new Row();
                var columnIndex = 0;

                foreach (var column in Model.Columns)
                {
                    var cell = new Cell();

                    try
                    {
                        var value = valueAccessors[columnIndex].GetValue(dataItem);
                        WriteCellValue(column, value, cell);
                    }
                    catch (Exception e)
                    {
                        throw new InvalidOperationException(string.Format(
                            "Excel column export error. Property name: {0}",
                            column.PropertyName
                        ), e);
                    }

                    row.Append(cell);

                    if (column.Width.HasValue == false)
                    {
                        var width = TextMeasure.GetCellWidth(cell);
                        SetColumnWidth(columnIndex, width);
                    }

                    columnIndex++;
                }

                SheetData.Append(row);
            }
        }

        // http://blogs.msdn.com/b/arvinwu/archive/2008/10/02/some-excel-2007-limitation.aspx
        const int MaxCellStringValueLength = 32767;

        void WriteCellValue(ExcelTableExporterColumn column, object value, Cell cell)
        {
            if (value == null)
            {
                cell.CellValue = new CellValue("");
                cell.DataType = CellValues.String;
                cell.StyleIndex = TableCommonCellFormat;
                return;
            }

            if (column.ValueConverter != null)
                value = column.ValueConverter(value);

            var culture = CultureInfo.InvariantCulture;

            if (column.ValueType == ExcelTableExporterValueTypes.String)
            {
                var stringValue = value.ToString();

                if (stringValue.Length > MaxCellStringValueLength)
                    stringValue = stringValue.Substring(0, MaxCellStringValueLength);

                cell.CellValue = new CellValue(stringValue);
                cell.DataType = CellValues.String;
                cell.StyleIndex = TableCommonCellFormat;
                return;
            }

            if (column.ValueType == ExcelTableExporterValueTypes.Number)
            {
                var decimalValue = Convert.ToDecimal(value);
                cell.CellValue = new CellValue(decimalValue.ToString(culture));
                cell.DataType = CellValues.Number;
                cell.StyleIndex = TableCommonCellFormat;
                return;
            }

            if (column.ValueType == ExcelTableExporterValueTypes.Boolean)
            {
                var boolValue = Convert.ToBoolean(value);
                cell.CellValue = new CellValue(boolValue ? "Да" : "");
                cell.DataType = CellValues.String;
                cell.StyleIndex = TableCommonCellFormat;
                return;
            }

            if (column.ValueType == ExcelTableExporterValueTypes.Date || column.ValueType == ExcelTableExporterValueTypes.DateTime)
            {
                var oaDateTimeValue = Convert.ToDateTime(value).ToOADate();
                cell.CellValue = new CellValue(oaDateTimeValue.ToString(culture));
                cell.DataType = CellValues.Number;
                cell.StyleIndex = column.ValueType == ExcelTableExporterValueTypes.Date ? TableDateCellFormat : TableDateTimeCellFormat;
                return;
            }

            throw new ArgumentException("column.ValueType");
        }

        #endregion

        #region Columns

        double[] ColumnWidths;

        void ResetColumnWidths()
        {
            ColumnWidths = new double[Model.Columns.Count];
        }

        void SetColumnWidth(int columnIndex, double width)
        {
            if (width > ColumnWidths[columnIndex])
                ColumnWidths[columnIndex] = width;
        }

        void WriteTableColumns()
        {
            var worksheetColumns = new Columns();
            var columnIndex = 0;

            foreach (var column in Model.Columns)
            {
                var columnNum = (uint)(columnIndex + 1);

                worksheetColumns.Append(new Column
                {
                    Min = columnNum,
                    Max = columnNum,
                    CustomWidth = true,
                    Width = column.Width ?? ColumnWidths[columnIndex]
                });

                columnIndex++;
            }

            Worksheet.InsertBefore(worksheetColumns, SheetData);
        }

        #endregion
    }
}


Есть надстройка ClosedXML . Я этим не пользовался, но на первый взгляд оно показалось удобным.

Если кто-то использовал проект ClosedXML, отпишите пожалуйста. Интересно Ваше мнение по поводу данного проекта.
...
Рейтинг: 0 / 0
сложная шапка в excel через Open XML SDK
    #38953205
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К,
это как бы уже этап пройденный, осталось изваять сложные шапки, и чето туплю как искать не вдуплюсь и сисы зажали скорость
как на дуалапе ((
...
Рейтинг: 0 / 0
сложная шапка в excel через Open XML SDK
    #38953208
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степии чето туплю как искать не вдуплюсьЕсли книга мутится "с нуля", то надо не искать, надо добавлять и запоминать индексы добавленного. Но это жесть.

Говорю же, попробуй ClosedXML, расскажешь потом. Там человеческая объектная модель, как в Excel OLE Automation.
...
Рейтинг: 0 / 0
сложная шапка в excel через Open XML SDK
    #38955456
Фотография Vakho
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КЕсть надстройка ClosedXML . Я этим не пользовался, но на первый взгляд оно показалось удобным.

Если кто-то использовал проект ClosedXML, отпишите пожалуйста. Интересно Ваше мнение по поводу данного проекта.

Довольно неплохая вещь. С её помощью я динамически строил страницы в EXCEL-e.
Работает только в NET Framework 3.5 и 4.x. для EXCEL 2007 или EXCEL 2010. Более поздние
версии не проверял.
Но есть одна неприятность. Мне понадобилось динамически формировать диаграммы.
А у ClosedXML-а похоже нет соответствующих свойств и методов.
Я отправил запрос к разработчику и на форум, но до сих пор ни ответа, ни привета.
...
Рейтинг: 0 / 0
сложная шапка в excel через Open XML SDK
    #38956985
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VakhoАлексей КЕсть надстройка ClosedXML . Я этим не пользовался, но на первый взгляд оно показалось удобным.

Если кто-то использовал проект ClosedXML, отпишите пожалуйста. Интересно Ваше мнение по поводу данного проекта.

Довольно неплохая вещь. С её помощью я динамически строил страницы в EXCEL-e.
Работает только в NET Framework 3.5 и 4.x. для EXCEL 2007 или EXCEL 2010. Более поздние
версии не проверял.
Но есть одна неприятность. Мне понадобилось динамически формировать диаграммы.
А у ClosedXML-а похоже нет соответствующих свойств и методов.
Я отправил запрос к разработчику и на форум, но до сих пор ни ответа, ни привета.Ок
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / сложная шапка в excel через Open XML SDK
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]