Форум программистов, компьютерный форум, киберфорум
Наши страницы

C# Windows Forms

Войти
Регистрация
Восстановить пароль
 
 
Cha1000000
2 / 2 / 1
Регистрация: 04.06.2015
Сообщений: 107
Записей в блоге: 1
#1

Сохранение/чтение/работа с файлами Excel без вызова СОМ (альтернативные методы) - C#

11.05.2017, 09:35. Просмотров 491. Ответов 16
Метки нет (Все метки)

Добрый день, коллеги!
Столкнулся с такой проблемой: в проекте Windows Forms реализовал сохранение в Excel файл (в два формата) таким образом
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
using Excel = Microsoft.Office.Interop.Excel;
 
namespace KKM_ProgBase_Utility
{
    public partial class fm_Main : Form
    {
        private Excel.Application ExcelApp;
        private Excel.Range excelcells;
 
        public fm_Main()
        {
            InitializeComponent();
        }
        
        private void mi_SaveToExcel_Click(object sender, EventArgs e)
        {//Сохранение в файлы Excel
            int i, j;
            saveTags.Title = "Экспорт в файл Excel";
            saveTags.Filter = "Файл Excel (*.xls) | *.xls |Файл Excel (*.csv) |*.csv";
 
            if (saveTags.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    Excel.Application ExcelApp = new Excel.Application();
                    Excel.Workbook workbook = ExcelApp.Workbooks.Add(Type.Missing);
                    Excel.Worksheet worksheet = workbook.ActiveSheet;
                    //Заголовок таблицы
                    for (j = 0; j < ProgTable.ColumnCount; j++)
                        ExcelApp.Cells[1, j + 1] = ProgTable.Columns[j].HeaderText;
                    //Данные
                    for (i = 0; i < ProgTable.Rows.Count; i++)
                    {
                        for (j = 0; j < ProgTable.ColumnCount; j++)
                        {
                            ExcelApp.Cells[i + 2, j + 1] = ProgTable.Rows[i].Cells[j].Value;
                        }
                    }
                    //////
                    ExcelApp.AlertBeforeOverwriting = false;
                    ExcelApp.DisplayAlerts = false; //Не запрашивать сохранение
                    //сохранение в .xls
                    if (saveTags.FilterIndex == 1)
                        ExcelApp.DefaultSaveFormat = Excel.XlFileFormat.xlExcel9795;
                    //сохранение в .csv
                    if (saveTags.FilterIndex == 2)
                        ExcelApp.DefaultSaveFormat = Excel.XlFileFormat.xlCSV;
                    //Установка типов данных и формат ячеек
                    excelcells = (Excel.Range)worksheet.Columns["C", Type.Missing];
                    excelcells.NumberFormat = "#####0";
                    //Cохранение файла
                    workbook.SaveAs(saveTags.FileName, ExcelApp.DefaultSaveFormat);
                    ExcelApp.Quit();
                }
                catch (Exception ex)
                {
                    //Обработка сбоя
                    ExcelApp.Quit();
                }
            }
        }
    }
}
Если на ПК установлен MS Office то этот код работает и всё хорошо сохраняет... Но! Есть такой нюанс: пробовал сохранить в Ексель-файл на компе, где Microsoft Office не установлен, либо стоит альтернативный офис типа Либры или OpenOffice... И такая конструкция уже не срабатывает!(( Выдает ошибки, что типа COM не зарегистрирован в системе и всё такое...
Отсюда у меня вопрос: как можно реализовать сохранение/открытие в/из файлов Ексель на форму программы, без вызова СОМ ну или каким-то образом, что бы привязок к Меклкософтовскому офису на ПК не было?
Заранее спасибо за помощь!
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.05.2017, 09:35
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Сохранение/чтение/работа с файлами Excel без вызова СОМ (альтернативные методы) (C#):

Сохранение картинки без вызова диалогового окна - C#
подскажите как сохранить измененную картинку? при всех попытках вызывается диалоговое окно, где нужно указать путь, имя и формат а...

Работа с файлами (чтение из файла) - C#
Кто-нибудь может помочь с заданием: В исходном текстовом файле подготовить данные о программе телепередач одного телевизионного канала на...

Работа с файлами. Пространство имён не может напрямую включать поля или методы - C#
Задание. Разработать программу Телефонный справочник, которая позволяет накапливать данные о контактах в текстовом файле. Читать записи из...

C# и работа с Excel файлами - C#
Доброе время суток! Меня зовут Павел, я пытаюсь освоить и в дальнейшем использовать Microsoft Visual Studio 2008. В данный момент у...

Работа с файлами Excel - C#
Здравствуйте! Нужен Ваш совет. Столкнулся с задачей обработки данных из Excel'евского файла: приходит файлик, приложение его корректирует...

Работа с Excel файлами - C#
Всем привет! Есть такой очень важный вопрос для меня... У меня есть файл xls, который я приложил к теме... У меня программа вычисляет день...

16
ViterAlex
6139 / 3356 / 1020
Регистрация: 11.02.2013
Сообщений: 7,437
Завершенные тесты: 3
11.05.2017, 09:39 #2
OpenXml. Можно начать с этого
0
Павлик Морозов
113 / 115 / 23
Регистрация: 26.10.2012
Сообщений: 382
Завершенные тесты: 1
11.05.2017, 10:19 #3
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Cha1000000, можно еще проще. Уже все придумали. Бесплатная библиотека EpPlus. Неоднократно использовал ее в своих проектах. Все просто и быстро делается. Пример работы с библиотекой можно почитать здесь
1
Cha1000000
2 / 2 / 1
Регистрация: 04.06.2015
Сообщений: 107
Записей в блоге: 1
11.05.2017, 10:55  [ТС] #4
Цитата Сообщение от Павлик Морозов Посмотреть сообщение
Уже все придумали. Бесплатная библиотека EpPlus.
И этот метод решает вопрос для альтернативных офисов? Если майкросовтовский на ПК не установлен, или например вообще никакого офиса нет на ПК, а сохранить из программы файл экселевского формата нужно?
Цитата Сообщение от Павлик Морозов Посмотреть сообщение
можно еще проще.
Проще, в смысле, чем в комментарии, предложенном выше?
0
Павлик Морозов
113 / 115 / 23
Регистрация: 26.10.2012
Сообщений: 382
Завершенные тесты: 1
11.05.2017, 11:04 #5
Cha1000000, эта библиотека решает проблему чтения/сохранения если вообще ничего не установлено на ПК, кроме .Net Framework. Ей не нужны никакие сторонние либо мелкософтовские решения/компоненты. Полностью самостоятельный продукт.
0
Cha1000000
2 / 2 / 1
Регистрация: 04.06.2015
Сообщений: 107
Записей в блоге: 1
11.05.2017, 11:17  [ТС] #6
Цитата Сообщение от Павлик Морозов Посмотреть сообщение
эта библиотека решает проблему чтения/сохранения если вообще ничего не установлено на ПК, кроме .Net Framework. Ей не нужны никакие сторонние либо мелкософтовские решения/компоненты. Полностью самостоятельный продукт.
Отлично! Огромное спасибо! Буду читать, смотреть разбираться!
0
Cha1000000
2 / 2 / 1
Регистрация: 04.06.2015
Сообщений: 107
Записей в блоге: 1
12.05.2017, 13:55  [ТС] #7
Цитата Сообщение от Павлик Морозов Посмотреть сообщение
эта библиотека решает проблему...
Добрый день! Покурил вчера инфу и примеры по, предложенной вами, библиотеке, и если я правильно понял, есть один огорчающий факт - библиотека работает только с .xlsx форматом, .xls (или на пример .csv) не поддерживает. Пока изучал материалы по данной библиотеке, нашёл, что есть ещё куча разных альтернативных библиотек на подобии этой (ну каждая, видимо, со своими особенностями). А вы можете ещё какую-то конкретную порекомендовать вместо EpPlus?
0
Usaga
Эксперт .NET
2605 / 2169 / 400
Регистрация: 21.01.2016
Сообщений: 8,418
Завершенные тесты: 2
12.05.2017, 14:04 #8
Cha1000000, XLS (как и DOC) - закрытый проприетарный формат. Сложно будет по нему инфу найти или нормальную библиотеку. CSV - открытый и очень простой формат, вы его сами сможете прочесть, без сторонних библиотек.
0
Cha1000000
2 / 2 / 1
Регистрация: 04.06.2015
Сообщений: 107
Записей в блоге: 1
12.05.2017, 14:28  [ТС] #9
Цитата Сообщение от Usaga Посмотреть сообщение
Сложно будет по нему инфу найти
А как же тогда с этими форматами работают альтернативные Китайские офисы типа Libra Office, OpenOffice, WPS Office и др.?
Цитата Сообщение от Usaga Посмотреть сообщение
вы его сами сможете прочесть, без сторонних библиотек.
Если можно немного поподробнее об этом?
0
Павлик Морозов
113 / 115 / 23
Регистрация: 26.10.2012
Сообщений: 382
Завершенные тесты: 1
13.05.2017, 17:49 #10
Cha1000000, для xls другая библиотека есть. Только Вам зачем этот формат? он же древний как прах мамонта
0
Cha1000000
2 / 2 / 1
Регистрация: 04.06.2015
Сообщений: 107
Записей в блоге: 1
14.05.2017, 00:48  [ТС] #11
Цитата Сообщение от Павлик Морозов Посмотреть сообщение
для xls другая библиотека есть. Только Вам зачем этот формат? он же древний как прах мамонта
Древний формат нужен потому, что разрабатываемая программа рассчитана на широкий круг потребителей. И не известно какой пакет офиса у них может быть установлен на ПК. Некоторые "динозавры", или хардкорщики ещё пользуются как ХР так офисом 2003, а тот в свою очередь, форма xlsx не поддерживает. Да, печально и досадно, что приходится позаботиться о такой совместимости, а не взять и тупо забыть про этот реликт, и смело писать сохранение/запись под xlsx формат... Но увы, что поделать... Приходится, пока "старьё" до конца не искоренится и не канет в лету, обеспечивать поддержку совместимости и всё такое...
Про библиотеку спасибо, тоже в процессе поиска сведений на ней пока остановился, разбираюсь и ищу годные примеры как по прямому импорту/экспорту из DataGreedView в xls, так и с использованием DataTable (с которым я пока дел не имел, не пользовался и не до конца пока разобрался). Буду так же признателен, если кто поделится такими примерами. Спасибо!
0
ViterAlex
6139 / 3356 / 1020
Регистрация: 11.02.2013
Сообщений: 7,437
Завершенные тесты: 3
14.05.2017, 01:12 #12
Цитата Сообщение от Cha1000000 Посмотреть сообщение
ищу годные примеры как по прямому импорту/экспорту из DataGreedView в xls
Используй csv. Он импортируется в любой Excel.
Цитата Сообщение от Cha1000000 Посмотреть сообщение
Некоторые "динозавры", или хардкорщики ещё пользуются как ХР так офисом 2003, а тот в свою очередь, форма xlsx не поддерживает.
Неправда. Поддерживает даже для Office 2000
0
Usaga
Эксперт .NET
2605 / 2169 / 400
Регистрация: 21.01.2016
Сообщений: 8,418
Завершенные тесты: 2
14.05.2017, 06:59 #13
Цитата Сообщение от Cha1000000 Посмотреть сообщение
Если можно немного поподробнее об этом?
Сохраните что-нибудь в данном формате, потом откройте файл в блокноте и всё сразу станет ясно...
0
Cha1000000
2 / 2 / 1
Регистрация: 04.06.2015
Сообщений: 107
Записей в блоге: 1
15.05.2017, 09:35  [ТС] #14
Цитата Сообщение от ViterAlex Посмотреть сообщение
Неправда. Поддерживает даже для Office 2000
О как интересно! Не знал. Тогда можно будет подумать о том, что бы забыть об .xls и полностью перейти на xlsx... Ну и csv пожалуй буду прикручивать (на всякий случай).
0
Cha1000000
2 / 2 / 1
Регистрация: 04.06.2015
Сообщений: 107
Записей в блоге: 1
30.05.2017, 10:17  [ТС] #15
Цитата Сообщение от Павлик Морозов Посмотреть сообщение
для xls другая библиотека есть
Спасибо ещё раз за информацию про библиотеку NPOI. Из грида по примеру выгрузить в эксель данные получилось, но пока только таким макаром, напрямую:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 // create xls if not exists
            if (!File.Exists("test.xls"))
            {
                wb = HSSFWorkbook.Create(InternalWorkbook.CreateWorkbook());
 
                // create sheet
                sh = (HSSFSheet)wb.CreateSheet("Лист1");
                // 3 rows, 2 columns
                for (int i = 0; i < 3; i++)
                {
                    var r = sh.CreateRow(i);
                    for (int j = 0; j < 2; j++)
                    {
                        r.CreateCell(j);
                    }
                }
                //создаёт файл и записывает туда данные
                using (var fs = new FileStream("test.xls", FileMode.Create, FileAccess.Write))
                {
                    wb.Write(fs);
                }
А вот привязать создание файла к компоненту SaveFileDialog не могу никак, обычные текстовые файлы уже много раз через него сохранял, а тут возникла проблема. Попробую пояснить её суть. Сначала код:
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
private void mi_SaveToExcel_Click(object sender, EventArgs e)
        {//Сохранение в файлы Excel
            int i, j;
 
            SaveDialog.Title = "Экспорт в файл Excel";
            SaveDialog.Filter = "Файлы Mirosoft Excel 97/2000/XP/2003(*.xls) | *.xls |Файлы Mirosoft Excel(*.csv) |*.csv";
 
            if (SaveDialog.ShowDialog() == DialogResult.OK)
            {
                if (SaveDialog.OpenFile() != null)
                {
                    //File_Name = Path.GetFileName(SaveDialog.FileName); //Имя файла 
                    File_Name = SaveDialog.FileName;   //имя файла с полным путём
                    
                    if (File.Exists(File_Name))
                    {
                        workbook = HSSFWorkbook.Create(InternalWorkbook.CreateWorkbook());
                        // create sheet
                        sheet = (HSSFSheet)workbook.CreateSheet("Лист1");
                        //Создание строк таблицы
                        for (i = 0; i < ProgTable.RowCount + 1; i++)
                        {
                            if (sheet.GetRow(i) == null)
                                sheet.CreateRow(i);
 
                            //Данные таблицы                                
                            for (j = 0; j < ProgTable.ColumnCount; j++)
                            {
                                if (sheet.GetRow(i).GetCell(j) == null)
                                    sheet.GetRow(i).CreateCell(j);
 
                                if (i == 0)//Заголовок таблицы
                                {
                                    sheet.GetRow(i).GetCell(j).SetCellValue(ProgTable.Columns[j].HeaderText);
                                }
                                else
                                    if (ProgTable[j, i - 1].Value != null)
                                    {
                                        sheet.GetRow(i).GetCell(j).SetCellValue(ProgTable[j, i - 1].Value.ToString());
                                    }
                            }
                        }
                        //Cохранение файла
                        using (var fs = new FileStream(File_Name, FileMode.Open, FileAccess.Write))
                        {
                            workbook.Write(fs);
                            MessageBox.Show("Данные успешно сохранены", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            fs.Close();
                        }
                    }
                }
            }
}
Итак, как я заметил, отлаживая пошагово, происходит следующее, при срабатывании "SaveDialog.ShowDialog() == DialogResult.OK" файл, имя которого ввели в окне SaveDialog, создаётся сразу, и как-то похоже удерживается процессом приложения, потому как дальше
C#
1
2
3
4
using (var fs = new FileStream(File_Name, FileMode.Open, FileAccess.Write))
                        {
                            workbook.Write(fs);
                        }
ничего не делает с созданным SaveDialog, файлом, пишет что он занят...

Вот такое сообщение: "Процесс не может получить доступ к файлу "D:\Documents\base.xls", так как этот файл используется другим процессом."

Может я что-то делаю не правильно и есть какой-то более верный способ сохранить в эксель данные через SaveFileDialog? Подскажите пожалуйста, а то уже как только не пробовал, ни в какую... Пробовал SaveDialog.Dispose(); вызвать после создания файла - не помогает. Может его как-то можно "освободить"?

Добавлено через 37 минут
Коллеги! Ответ из серии: "сам спросил, сам ответил".
Я уже сам успел разобраться и найти решение. И для тех, кому интересно и может быть полезным, расскажу в чём была суть.
В общем да, SaveDialog создавал и удерживал файл, и для этого понадобилось перехватить его поток и потом закрыть его, что бы освободить файл. Создал поток:
C#
1
Stream myStream;
за тем перехватил:
C#
1
if ((myStream = SaveDialog.OpenFile()) != null)
и позже закрыл его:
C#
1
myStream.Close();
В итоге получился рабочий код:
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
private void mi_SaveToExcel_Click(object sender, EventArgs e)
        {//Сохранение в файлы Excel
            int i, j;
 
            SaveDialog.Title = "Экспорт в файл Excel";
            SaveDialog.Filter = "Файлы Mirosoft Excel 97/2000/XP/2003(*.xls) | *.xls |Файлы Mirosoft Excel(*.csv) |*.csv";
            Stream myStream;
            if (SaveDialog.ShowDialog() == DialogResult.OK)
            {
                if ((myStream = SaveDialog.OpenFile()) != null)
                {
                    //File_Name = Path.GetFileName(SaveDialog.FileName); //Имя файла 
                    File_Name = SaveDialog.FileName;   //имя файла с полным путём
                    myStream.Close();
                    try
                    {
                        if (File.Exists(File_Name))
                        {
                            workbook = HSSFWorkbook.Create(InternalWorkbook.CreateWorkbook());
                            // create sheet
                            sheet = (HSSFSheet)workbook.CreateSheet("Лист1");
 
                            //Создание строк таблицы
                            for (i = 0; i < ProgTable.RowCount + 1; i++)
                            {
                                if (sheet.GetRow(i) == null)
                                    sheet.CreateRow(i);
 
                                //Данные таблицы                                
                                for (j = 0; j < ProgTable.ColumnCount; j++)
                                {
                                    if (sheet.GetRow(i).GetCell(j) == null)
                                        sheet.GetRow(i).CreateCell(j);
 
                                    if (i == 0)//Заголовок таблицы
                                    {
                                        sheet.GetRow(i).GetCell(j).SetCellValue(ProgTable.Columns[j].HeaderText);
                                    }
                                    else
                                        if (ProgTable[j, i - 1].Value != null)
                                        {
                                            sheet.GetRow(i).GetCell(j).SetCellValue(ProgTable[j, i - 1].Value.ToString());
                                        }
                                }
                            }
                            //Cохранение файла
                            using (var fs = new FileStream(File_Name, FileMode.Open, FileAccess.Write))
                            {
                                workbook.Write(fs);
                                MessageBox.Show("Данные успешно сохранены", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                fs.Close();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        //Обработка сбоя
                        MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }            
        }
0
30.05.2017, 10:17
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.05.2017, 10:17
Привет! Вот еще темы с ответами:

Чтение данных из сом по событию - C#
Как реализовать чтение данных из порта только в том случае, если в его буфере появились данные?

Как сделать паузу без подвисания и без вызова Sleep? - C#
Здравствуйте, как можно сделать паузу без &quot;второго&quot; потока и вешания программы посредством System.Threading.Thread.Sleep? ...

Работа с excel без установленного Офиса - C#
Доброго времени суток. Подскажите пожалуйста библиотеку для работы с excel ( экспорт данных в xls файлы) без установленного офиса. Хорошо...

Работа с Excel 2007 без установленного MS Office - C#
Здравствуйте. вопрос такой: на компе не установлен Excel 2007, прога работает с Interop ver.12 работа с файлами 2003 проходит на ура,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.