powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Слить много файлов в формате .csv в один Эксель файл
17 сообщений из 17, страница 1 из 1
Слить много файлов в формате .csv в один Эксель файл
    #39840281
Фотография Roust_m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день,

Пытаюсь создать програмку, которая вытаскивает схему таблиц из базы в csv (каждая таблица в отдельный файл) и потом собирает эти файлы в один .xlsx файл (каждый csv в отдельный sheet в экселе).

Ниже код, который у меня получился. Тот модуль, который создает csv я написал сам (спасибо всем за помощь в соседнем топике), он работает замечательно. (Сильно не ругайте, ибо опыта программирования у меня почти нет).

Модуль который собирает csv в один эксель файл я нашел в интернете и он работает только в идеальных условиях.

Например, ему не нравится если в файлах присутствует шапка (выделено жирным), а также ругается на слова типа "System":
dbo.assessment
<< Go to main list

TABLE_SCHEMA , TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, CONSTRAINT, Notes, Join Information
dbo,assessment,id,1,,bigint,8,,,
dbo,assessment,created_by,17,(' System '),varchar,80,,,
dbo,assessment,created_date,18,(getdate()),datetime,,,,

Вот некоторые ошибки:
System.Data.OleDb.OleDbException (0x80040E14): Syntax error (missing operator) in query expression ''('System')''.
System.Data.OleDb.OleDbException (0x80040E14): Invalid bracketing of name '[dbo.assessment]'.
System.Data.OleDb.OleDbException (0x80004005): ' TABLE_NAME' is not a valid name. Make sure that it does not include invalid characters or punctuation and that it is not too long.
System.Data.OleDb.OleDbException (0x80004005): '' is not a valid name. Make sure that it does not include invalid characters or punctuation and that it is not too long.

Вот примеры файлов, который надо слить в один:
https://1drv.ms/u/s!At756qpwT4ushdplPIsW3pot5AckbA?e=byMZgt


Помогите пжлста подправить модуль, который сливает файлы в один, чтобы он работал со всеми данными.

Спасибо.


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Document_Database
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Starting the app");
            var buildCSVs = new BuildCSVs();
            buildCSVs.CSVExport();
            var mergeCSVs = new MergeCSVs();
            mergeCSVs.CSVMerge();
            Console.ReadLine();
        }
    }
}



Код: 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.
using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Document_Database
{
    class BuildCSVs
    {
        public void CSVExport()
        {
            string connectionString = "Data Source=localhost;" + "Initial Catalog=AdventureWorks2017;Integrated Security=SSPI";
            string tblListSQL = "SELECT s.name schname, o.name tblname FROM sys.objects o JOIN sys.schemas s on o.schema_id = s.schema_id WHERE o.type = 'U' AND o.name NOT IN ('sysdiagrams') ORDER BY o.name;";
            // Create ADO.NET objects.
            SqlConnection con = new SqlConnection(connectionString);
            SqlCommand cmd = new SqlCommand(tblListSQL, con);

            // Execute the command.
            con.Open();

            //int rowsAffected = 
            //string[] tableList = cmd.ExecuteNonQuery();
            int i = 1;
            //string[] names = new string[128];
            var Reader = cmd.ExecuteReader();
            string tblName;
            string schName;
            if (Reader.HasRows)
            {
                while (Reader.Read())
                {
                    //Console.WriteLine(String.Format("{0}", Reader["name"]));
                    tblName = String.Format("{0}", Reader["tblname"]);
                    schName = String.Format("{0}", Reader["schname"]);
                    //Console.WriteLine(tblName);
                    tableInfo(schName, tblName);

                    i += 1;
                }
            }
            Reader.Close();
            con.Close();
        }
        private void tableInfo(string schName, string tblName)
        {
            Console.WriteLine(schName + '.' + tblName);
            Console.WriteLine("<< Go to main list");
            string connectionString = "Data Source=localhost;" + "Initial Catalog=AdventureWorks2017;Integrated Security=SSPI";
            string tblInfoSQL = "dbo.uspTableInfo";
            // Create ADO.NET objects.
            SqlConnection con = new SqlConnection(connectionString);
            SqlCommand cmd = new SqlCommand(tblInfoSQL, con);
            cmd.CommandType = CommandType.StoredProcedure;
            SqlParameter param;
            param = cmd.Parameters.Add("@schema_name", SqlDbType.VarChar, 128);
            param.Value = schName;
            param = cmd.Parameters.Add("@table_name", SqlDbType.VarChar, 128);
            param.Value = tblName;

            // Execute the command.
            con.Open();
            //int rowsAffected = cmd.ExecuteNonQuery();
            string filename = @"C:\temp\Junk\" + schName + '_' + tblName + ".csv";
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(filename))
            {
                file.WriteLine(schName + '.' + tblName);
                file.WriteLine("<< Go to main list");
                file.WriteLine(" ");
                file.WriteLine("TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME,ORDINAL_POSITION,COLUMN_DEFAULT,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,CONSTRAINT,Notes,Join Information");
            
            var Reader = cmd.ExecuteReader();
            int i = 1;
            string tableName;
            string schemaName;
            string columnName;
            string ordinalPosition;
            string columnDefault;
            string dataType;
            string charMaxLength;
            string constraint;
            string notes;
            string joinInfo;

            if (Reader.HasRows)
            {
                while (Reader.Read())
                {
                    tableName = String.Format("{0}", Reader["TABLE_NAME"]);
                    schemaName = String.Format("{0}", Reader["TABLE_SCHEMA"]);
                    columnName = String.Format("{0}", Reader["COLUMN_NAME"]);
                    ordinalPosition = String.Format("{0}", Reader["ORDINAL_POSITION"]);
                    columnDefault = String.Format("{0}", Reader["COLUMN_DEFAULT"]);
                    dataType = String.Format("{0}", Reader["DATA_TYPE"]);
                    charMaxLength = String.Format("{0}", Reader["CHARACTER_MAXIMUM_LENGTH"]);
                    constraint = String.Format("{0}", Reader["CONSTRAINT"]);
                    notes = String.Format("{0}", Reader["Notes"]);
                    joinInfo = String.Format("{0}", Reader["Join Information"]);
                    file.WriteLine(schemaName + "," + tableName + "," + columnName + "," + ordinalPosition + "," + columnDefault + "," + dataType + "," + charMaxLength + "," + constraint + "," + notes + "," + joinInfo);
                    i += 1;
                }
            }
            Reader.Close();
            }
            con.Close();
            return;
        }
    }
}




Код: 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.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Added below name spaces
using System.IO;
using System.Data.OleDb;


namespace Document_Database
{
    class MergeCSVs
    {
        public void CSVMerge()
        //static void Main(string[] args)
        {
            //the datetime and Log folder will be used for error log file in case error occured
            string datetime = DateTime.Now.ToString("yyyyMMddHHmmss");
            string LogFolder = @"C:\temp\Log\";
            try
            {
                //Declare Variables
                //Provide the source folder path
                string SourceFolderPath = @"C:\Temp\Junk\";
                //Provide the Destination folder path
                string DestinationFolderPath = @"C:\Temp\Destination\";
                //Provide the extension of input files such as .csv or .txt
                string FileExtension = ".csv";
                //Provide the file delimiter such as comma or pipe
                string FileDelimiter = ",";
                //Provide the Excel file name that you want to create
                string ExcelFileName = "AllTables";
                string CreateTableStatement = "";
                string ColumnList = "";

                //Reading file names one by one
                string SourceDirectory = SourceFolderPath;
                string[] fileEntries = Directory.GetFiles(SourceDirectory, "*" + FileExtension);
                foreach (string fileName in fileEntries)
                {


                    //Read first line(Header) and prepare Create Statement for Excel Sheet
                    System.IO.StreamReader file = new System.IO.StreamReader(fileName);
                    string filenameonly = (((fileName.Replace(SourceDirectory, "")).Replace(FileExtension, "")).Replace("\\", ""));
                    CreateTableStatement = (" Create Table [" + filenameonly + "] (["
                        + file.ReadLine().Replace(FileDelimiter, "] Text,["))
                        + "] Text)";
                    file.Close();

                    //Construct ConnectionString for Excel
                    string connstring = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + DestinationFolderPath + "\\" + ExcelFileName + "_" + datetime
                        + ";" + "Extended Properties=\"Excel 12.0 Xml;HDR=YES;\"";
                    OleDbConnection Excel_OLE_Con = new OleDbConnection();
                    OleDbCommand Excel_OLE_Cmd = new OleDbCommand();

                    Excel_OLE_Con.ConnectionString = connstring;
                    Excel_OLE_Con.Open();
                    Excel_OLE_Cmd.Connection = Excel_OLE_Con;

                    //Use OLE DB Connection and Create Excel Sheet
                    Excel_OLE_Cmd.CommandText = CreateTableStatement;
                    Excel_OLE_Cmd.ExecuteNonQuery();

                    //Writing Data of File to Excel Sheet in Excel File
                    int counter = 0;
                    string line;

                    System.IO.StreamReader SourceFile =
                    new System.IO.StreamReader(fileName);
                    while ((line = SourceFile.ReadLine()) != null)
                    {
                        if (counter == 0)
                        {
                            ColumnList = "[" + line.Replace(FileDelimiter, "],[") + "]";

                        }
                        else
                        {
                            string query = "Insert into [" + filenameonly + "] ("
                                + ColumnList + ") VALUES('"
                                + line.Replace(FileDelimiter, "','")
                                + "')";
                            var command = query;
                            Excel_OLE_Cmd.CommandText = command;
                            Excel_OLE_Cmd.ExecuteNonQuery();

                        }
                        counter++;
                    }
                    Excel_OLE_Con.Close();
                    SourceFile.Close();

                }
            }

            catch (Exception exception)
            {
                // Create Log File for Errors
                using (StreamWriter sw = File.CreateText(LogFolder
                    + "\\" + "ErrorLog_" + datetime + ".txt"))
                {
                    sw.WriteLine(exception.ToString());

                }

            }

        }
    }
}





Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CREATE PROCEDURE [dbo].[uspTableInfo] (@schema_name sysname, @table_name sysname)
AS
BEGIN
    SET NOCOUNT ON;
	SELECT s.name TABLE_SCHEMA, so.name TABLE_NAME, SC.NAME COLUMN_NAME, sc.colorder ORDINAL_POSITION, ISNULL(sm.text, '') COLUMN_DEFAULT, t.name DATA_TYPE, CASE WHEN sc.isnullable = 0 THEN 'NOT NULL' ELSE 'NULL' END IS_NULLABLE, 
	CASE WHEN t.name NOT IN('int', 'hierarchyid', 'geometry', 'geography', 'uniqueidentifier', 'datetime', 'tinyint', 'smallint', 'decimal', 'datetime2', 'datetimeoffset', 'image', 'money', 'numeric', 'real', 'smalldatetime', 'smallint', 'smallmoney', 'time', 'timestamp', 'tinyint') THEN sc.length END CHARACTER_MAXIMUM_LENGTH, ''[CONSTRAINT], '' Notes, ''[Join Information]
	FROM dbo.sysobjects so
	INNER JOIN dbo.syscolumns sc ON so.id = sc.id
	JOIN sys.schemas s on so.uid = s.schema_id
	LEFT JOIN dbo.syscomments sm ON sc.cdefault = sm.id
	JOIN systypes t on t.xtype = sc.xtype
	WHERE so.xtype = 'U' and so.name = @table_name and s.name = @schema_name
	ORDER BY so.[name], sc.colid; 
	SET NOCOUNT OFF;
END;
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39840296
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roust_mSystem.Data.OleDb.OleDbException (0x80040E14): Syntax error (missing operator) in query expression ''('System')''.
System.Data.OleDb.OleDbException (0x80040E14): Invalid bracketing of name '[dbo.assessment]'.
System.Data.OleDb.OleDbException (0x80004005): ' TABLE_NAME' is not a valid name. Make sure that it does not include invalid characters or punctuation and that it is not too long.
System.Data.OleDb.OleDbException (0x80004005): '' is not a valid name. Make sure that it does not include invalid characters or punctuation and that it is not too long.Вряд ли кто-то найдет желание заниматься вашим проектом в целом, это требует времени. Вычленяйте ошибки и разбирайтесь с каждой из них по отдельности. Тем более, все указанные ошибки - это ошибки в синтаксисе SQL, к примеру вместо [dbo.assessment] надо написать [dbo].[assessment] или просто dbo.assessment. Поэтому нужно просто брать результирующий запрос (собранную строку, которая пытается выполниться как SQL-команда), пытаться выполнить ее в sql-студии и, если студия выдала ту же ошибку, разбираться с синтаксисом, в частности, задать конкретный вопрос (здесь или даже в разделе mssql)
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39840312
Фотография Roust_m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProRoust_mSystem.Data.OleDb.OleDbException (0x80040E14): Syntax error (missing operator) in query expression ''('System')''.
System.Data.OleDb.OleDbException (0x80040E14): Invalid bracketing of name '[dbo.assessment]'.
System.Data.OleDb.OleDbException (0x80004005): ' TABLE_NAME' is not a valid name. Make sure that it does not include invalid characters or punctuation and that it is not too long.
System.Data.OleDb.OleDbException (0x80004005): '' is not a valid name. Make sure that it does not include invalid characters or punctuation and that it is not too long.Вряд ли кто-то найдет желание заниматься вашим проектом в целом, это требует времени. Вычленяйте ошибки и разбирайтесь с каждой из них по отдельности. Тем более, все указанные ошибки - это ошибки в синтаксисе SQL, к примеру вместо [dbo.assessment] надо написать [dbo].[assessment] или просто dbo.assessment. Поэтому нужно просто брать результирующий запрос (собранную строку, которая пытается выполниться как SQL-команда), пытаться выполнить ее в sql-студии и, если студия выдала ту же ошибку, разбираться с синтаксисом, в частности, задать конкретный вопрос (здесь или даже в разделе mssql)

Так я так и пишу:
Код: c#
1.
2.
3.
                file.WriteLine(schName + '.' + tblName);
                file.WriteLine("<< Go to main list");
                file.WriteLine(" ");


В файле у меня:
dbo.assessment
<< Go to main list

TABLE_SCHEMA , TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, CONSTRAINT, Notes, Join Information
dbo,assessment,id,1,,bigint,8,,,
dbo,assessment,created_by,17,(' System '),varchar,80,,,
dbo,assessment,created_date,18,(getdate()),datetime,,,,

Если в примере выше убрать строки с именем таблицы, текстом "<< Go to main list" и пустой строки после этого текста и убрать слово "System" из определния таблицы, то все работает:
TABLE_SCHEMA , TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, CONSTRAINT, Notes, Join Information
dbo,assessment,id,1,,bigint,8,,,
dbo,assessment,created_by,17,,varchar,80,,,
dbo,assessment,created_date,18,(getdate()),datetime,,,,

Вот команда, на которой это все валится:
Insert into [dbo_assessment] ([dbo.assessment]) VALUES('<< Go to main list')
Такая ошибка
"Invalid bracketing of name '[dbo.assessment]'."

Она думает, что имя таблицы в первой строке есть имя столбца: dbo.assessment
А мне надо просто содержимое CSV вставить без всяких заголовков (имен столбцов).

Также она ругается на слово "system" в определении таблицы.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
                   while ((line = SourceFile.ReadLine()) != null)
                    {
                        if (counter == 0)
                        {
                            ColumnList = "[" + line.Replace(FileDelimiter, "],[") + "]";

                        }
                        else
                        {
                            string query = "Insert into [" + filenameonly + "] ("
                                + ColumnList + ") VALUES('"
                                + line.Replace(FileDelimiter, "','")
                                + "')";
                            var command = query;
                            Excel_OLE_Cmd.CommandText = command;
                            Excel_OLE_Cmd.ExecuteNonQuery();

                        }
                        counter++;
                    }
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39840730
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roust_mInsert into [dbo_assessment] ( [dbo.assessment] ) VALUES('<< Go to main list')
Такая ошибка
"Invalid bracketing of name '[dbo.assessment]'."

Она думает, что имя таблицы в первой строке есть имя столбца: dbo.assessmentТы же сам написал такое имя столбца, а не "она думает". Точка не допускается в имени столбца.
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39840733
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roust_m' TABLE_NAME' is not a valid name. Make sure that it does not include invalid characters or punctuation and that it is not too long.тут он говорит, что в имени таблицы не может быть пробела
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39840735
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roust_mМодуль который собирает csv в один эксель файл я нашел в интернете и он работает только в идеальных условиях.Roust_mему не нравится если в файлах присутствует...Что-то я не пойму, причем тут идеальные условия? Ты взял некий сторонний код, который читает файл в определенном формате, и решил, что он должен работать, если ты будешь писать в исходный файл всякую случайную фигню. Либо обеспечивай ему требования к формату, либо переделывай так, чтобы он понимал твои файлы в некоем другом формате
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39840737
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roust_mна слова типа "System":он не ругается на слова System, они ему вообще пофиг. Он ругается, из-за того, что у тебя используется одиночный апостроф в значении. Апострофы нужно удваивать внутри текстового литерала, обрамленного апострофами - это синтаксис sql. Достаточно было бы Replace(val, "'", "''"), но автор скрипта не удосужился это сделать, как и попытки удалять лишние пробелы в названиях таблиц и полей.
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39840759
Фотография Roust_m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProRoust_mМодуль который собирает csv в один эксель файл я нашел в интернете и он работает только в идеальных условиях.Roust_mему не нравится если в файлах присутствует...Что-то я не пойму, причем тут идеальные условия? Ты взял некий сторонний код, который читает файл в определенном формате, и решил, что он должен работать, если ты будешь писать в исходный файл всякую случайную фигню. Либо обеспечивай ему требования к формату, либо переделывай так, чтобы он понимал твои файлы в некоем другом формате

А как сделать так, чтобы он импортировал данные без имен столбцов, просто как данные, при этом, чтобы число столбцов в разных строках могло быть разным?
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39840761
Фотография Roust_m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно как-нибудь просто скопировать диапазон, скажем A1:Z100?
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39840769
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то тут совсем всё печально. Во-первых, есть системные представления information_schema.columns и information_schema.tables , которые предоставляют всю нужную информацию без конструирования сложносочиненных запросов, да к тому же с использованием устаревших представлений ( sysobjects итп).
Во-вторых, наиболее оптимально эту задачу решать генерацией файла в формате Excel XML Spreadsheet - на вход xml-данные, сформированные запросом, и преобразование данных с помощью XSLT - на выходе сразу получаем файл нужной структуры, который только останется красиво отформатировать, и сохранить в .xslx.
Запрос для предоставления xml-данных:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
select
  [table].table_schema,
  [table].table_name,
  [column].column_name,
  [column].ordinal_position,
  [column].column_default,
  [column].data_type,
  [column].is_nullable,
  [column].character_maximum_length
from information_schema.tables [table]
join information_schema.columns [column] on
  [column].table_schema=[table].table_schema and
  [column].table_name=[table].table_name
where [table].table_schema<>'sysdiagrams' and [table].table_type='BASE TABLE'
order by 1,2,4
for xml auto, root, type


XSLT-преобразование:
Код: xml
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.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
  version="1.0"
  xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
  xmlns:x="urn:schemas-microsoft-com:office:excel"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" />
  <xsl:template match="/">
    <xsl:processing-instruction name="mso-application">
      <xsl:text>progid="Excel.Sheet"</xsl:text>
    </xsl:processing-instruction>
    <ss:Workbook
      xmlns="urn:schemas-microsoft-com:office:spreadsheet"
      xmlns:o="urn:schemas-microsoft-com:office:office"
      xmlns:x="urn:schemas-microsoft-com:office:excel"
      xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
      xmlns:html="http://www.w3.org/TR/REC-html40">
      <ss:Styles>
        <ss:Style ss:ID="sH1"><ss:Font ss:Bold="1"/></ss:Style>
      </ss:Styles>
      <xsl:apply-templates />
    </ss:Workbook>
  </xsl:template>
  <xsl:template match="root">
    <xsl:apply-templates />
  </xsl:template>
  <xsl:template match="table">
    <ss:Worksheet>
      <xsl:attribute namespace="urn:schemas-microsoft-com:office:spreadsheet" name="Name">
        <xsl:value-of select="substring(concat(@table_schema, '.', @table_name), 0, 32)" />
      </xsl:attribute>
      <ss:Table>
        <ss:Row>
          <ss:Cell ss:StyleID="sH1"><ss:Data ss:Type="String">column_name</ss:Data></ss:Cell>
          <ss:Cell ss:StyleID="sH1"><ss:Data ss:Type="String">ordinal_position</ss:Data></ss:Cell>
          <ss:Cell ss:StyleID="sH1"><ss:Data ss:Type="String">column_default</ss:Data></ss:Cell>
          <ss:Cell ss:StyleID="sH1"><ss:Data ss:Type="String">data_type</ss:Data></ss:Cell>
          <ss:Cell ss:StyleID="sH1"><ss:Data ss:Type="String">is_nullable</ss:Data></ss:Cell>
          <ss:Cell ss:StyleID="sH1"><ss:Data ss:Type="String">character_maximum_length</ss:Data></ss:Cell>
          <ss:Cell ss:StyleID="sH1"><ss:Data ss:Type="String">CONSTRAINT</ss:Data></ss:Cell>
          <ss:Cell ss:StyleID="sH1"><ss:Data ss:Type="String">Notes</ss:Data></ss:Cell>
          <ss:Cell ss:StyleID="sH1"><ss:Data ss:Type="String">Join Information</ss:Data></ss:Cell>
        </ss:Row>
        <xsl:apply-templates />
      </ss:Table>
    </ss:Worksheet>
  </xsl:template>
  <xsl:template match="column">
    <ss:Row>
      <ss:Cell><ss:Data ss:Type="String"><xsl:value-of select="@column_name" /> </ss:Data></ss:Cell>
      <ss:Cell><ss:Data ss:Type="String"><xsl:value-of select="@ordinal_position" /> </ss:Data></ss:Cell>
      <ss:Cell><ss:Data ss:Type="String"><xsl:value-of select="@column_default" /> </ss:Data></ss:Cell>
      <ss:Cell><ss:Data ss:Type="String"><xsl:value-of select="@data_type" /> </ss:Data></ss:Cell>
      <ss:Cell><ss:Data ss:Type="String"><xsl:value-of select="@is_nullable" /> </ss:Data></ss:Cell>
      <ss:Cell><ss:Data ss:Type="Number"><xsl:value-of select="@character_maximum_length" /> </ss:Data></ss:Cell>
      <ss:Cell />
      <ss:Cell />
      <ss:Cell />
    </ss:Row>
  </xsl:template>
</xsl:stylesheet>


Использование:
Код: 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.
class Program
{
  public static void Main(string[] args)
  {
    var xsl = new XslCompiledTransform();
    using(var sr = new StringReader(Properties.Resources.DataTransform))
    using(var xr = XmlReader.Create(sr))
        xsl.Load(xr);
    using(var cnn = new SqlConnection("Data Source=.;Initial Catalog=AdventureWorks2017;Integrated Security=SSPI"))
    using(var cmd = new SqlCommand(Properties.Resources.TablesQuery, cnn))
    using(var fs = new FileStream(@"D:\Trash\tables.xml", FileMode.Create))
    using(var xw = XmlWriter.Create(fs, new XmlWriterSettings
    {
      Indent = true,
      IndentChars = "  ",
      OmitXmlDeclaration = false
    }))
    {
      cnn.Open();
      using(var rd = cmd.ExecuteReader())
      {
        if (!rd.Read()) throw new ApplicationException("No data");
        if (rd.IsDBNull(0)) throw new ApplicationException("Data is null");
        using(var xr = rd.GetSqlXml(0).CreateReader())
          xsl.Transform(xr, null, xw);
      }
    }
    Console.WriteLine("done");
    Console.ReadKey(true);
  }
}


Нюансы:
1. У экселя, в т.ч. и у последних версий, есть ограничение на длину имени листа - 31 символ, поэтому в xsl-шаблоне при формировании имени листа используется substring.
2. В вышеприведенном коде ображение и к запросу, и к шаблону делается как к ресурсам. За вхардкоденные запросы кое-где можно схлопотать (да и с ними просто тупо неудобно работать).
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39840773
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roust_mА как сделать так, чтобы он импортировал данные без имен столбцов, просто как данные, при этом, чтобы число столбцов в разных строках могло быть разным?А что тогда мешает открыть этот файл в экселе как csv без всяких там скриптов, это же штатная возможность экселя
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39841751
Фотография Roust_m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны,

Не совсем понял как это работает. Если мы запросом создаем xml файл, то зачем нам подключаться к базе?
using(var cnn = new SqlConnection("Data Source=.;Initial Catalog=AdventureWorks2017;Integrated Security=SSPI"))

Также не совсем понял, куда эта программа пишет? А также куда присобачить XSLT-преобразование?

Я так понимаю что программа берет файл сгенерированный запросом: "D:\Trash\tables.xml"

А результат куда отправляется?

Пытался скопилировать, ругается на эти строки:
Код: c#
1.
2.
3.
            using (var sr = new StringReader(Properties.Resources.DataTransform))
...
            using (var cmd = new SqlCommand(Properties.Resources.TablesQuery, cnn))


The name 'Properties' does not exist in the current context
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39841752
Фотография Roust_m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProRoust_mА как сделать так, чтобы он импортировал данные без имен столбцов, просто как данные, при этом, чтобы число столбцов в разных строках могло быть разным?А что тогда мешает открыть этот файл в экселе как csv без всяких там скриптов, это же штатная возможность экселя

Я попробовал такой подход, в котором открываю каждый из csv файлов и тупо копирую диапазон A1:J60.

Почему-то ругается на то, что диапазоны источника и цели разные, хотя оба определены как A1:J60.
Код: 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.
using System;
using System.IO;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;

namespace Document_Database
{
    class CopyCSV
    {
        public void CSVCopy()
        {

            Excel.Application srcApp;
            Excel.Workbook srcWorkbook;
            Excel.Worksheet srcWorksheet;

            Excel.Application destApp;
            Excel.Workbook destWorkbook;
            Excel.Worksheet destWorksheet;

            string datetime = DateTime.Now.ToString("yyyyMMddHHmmss");
            string LogFolder = @"C:\temp\Log\";

            //Declare Variables
            //Provide the source folder path
            string SourceFolderPath = @"C:\Temp\Junk\";
            //Provide the Destination folder path
            string DestinationFolderPath = @"C:\Temp\Destination\";
            //Provide the extension of input files such as .csv or .txt
            string FileExtension = ".csv";
            //Provide the file delimiter such as comma or pipe
            //string FileDelimiter = ",";
            //Provide the Excel file name that you want to create
            string ExcelFileName = "AllTables";
            //string CreateTableStatement = "";
            //string ColumnList = "";

            int i =1;

            //Reading file names one by one
            string SourceDirectory = SourceFolderPath;
            destApp = new Excel.Application();
            string destPath = DestinationFolderPath + ExcelFileName + ".xlsx";
            destWorkbook = destApp.Workbooks.Open(destPath, 0, false);
            string[] fileEntries = Directory.GetFiles(SourceDirectory, "*" + FileExtension);
            foreach (string fileName in fileEntries)
            {
                System.IO.StreamReader file = new System.IO.StreamReader(fileName);
                string filenameonly = (((fileName.Replace(SourceDirectory, "")).Replace(FileExtension, "")).Replace("\\", ""));
                string srcPath = SourceFolderPath + filenameonly + ".csv";
                srcApp = new Excel.Application();
                srcWorkbook = srcApp.Workbooks.Open(srcPath);
                srcWorksheet = srcWorkbook.Worksheets.get_Item(1);
                Excel.Range srcRange = srcWorksheet.get_Range("A1", "J60");



                //worKbooK = excel.Workbooks.Add(Type.Missing);
                //var xlNewSheet = destWorkbook.Worksheets.Add(filenameonly);
                //var xlSheets = destWorkbook.Sheets as Excel.Sheets;
                //var xlNewSheet = (Excel.Worksheet)xlSheets.Add(xlSheets[i], Type.Missing, Type.Missing, Type.Missing);
                //var xlNewSheet = (Excel.Worksheet)destWorkbook.Worksheets.Add(Type.Missing, destWorkbook.Worksheets[destWorkbook.Worksheets.Count], Type.Missing, Type.Missing);
                //xlNewSheet.Name = filenameonly;

                //var worKsheeT = (Microsoft.Office.Interop.Excel.Worksheet)destWorkbook.ActiveSheet;
                var worksheet = destWorkbook.Worksheets.Add(Type.Missing, Type.Missing, Type.Missing, Type.Missing);

                string wsName = "";
                if (filenameonly.Length > 31)
                    wsName = filenameonly.Substring(1, 31);
                else wsName = filenameonly;

                worksheet.Name = wsName;
                //xlNewSheet.Cells[1, 1] = "New sheet content";

                destWorksheet = destWorkbook.Worksheets.get_Item(1);
                Excel.Range destRange = destWorksheet.get_Range("A1", "J60");


                srcRange.Copy(Type.Missing);
                //_ = destRange.PasteSpecial(Microsoft.Office.Interop.Excel.XlPasteType.xlPasteValues, Microsoft.Office.Interop.Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone);
                Console.WriteLine("Source: " + srcPath + ":" + "srcWorksheet" + " Destination: " + destPath + ":" + destWorksheet);

                destApp.DisplayAlerts = false;
                destWorkbook.SaveAs(DestinationFolderPath + ExcelFileName + "_" + datetime + ".xlsx", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing,
                            Type.Missing, Type.Missing);

                i++;
                srcApp.Application.DisplayAlerts = false;
                srcWorkbook.Close(false, null, null);
                srcApp.Quit();
            }
            destApp.Application.DisplayAlerts = false;
            destWorkbook.Close(true, null, null);
            destApp.Quit();
        }


    }
}
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39841753
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roust_mЕсли мы запросом создаем xml файл
Запросом мы получаем данные от сервера в виде xml.
Roust_mТакже не совсем понял, куда эта программа пишет?
В файл D:\Trash\tables.xml
Roust_mА также куда присобачить XSLT-преобразование?
Оно туда уже присобачено.
Roust_mА результат куда отправляется?
В файл D:\Trash\tables.xml
Roust_mПытался скопилировать, ругается на эти строки:
Комментарий №2 в моем предыдущем постинге.
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39841762
Фотография Roust_m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны,

Разобрался, шикарное решение, спасибо большое!
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39841776
Фотография Roust_m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны,

Такой еще вопрос, а что нужно сделать, чтобы на каждом листе помимо информации о структуре таблицы была шапка в виде схемы и имени таблицы и текста "<< Go to main list" за которым пустая строка и затем уже данные из запроса:

dbo.assessment
<< Go to main list


TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT DATA_TYPE CHARACTER_MAXIMUM_LENGTH CONSTRAINT Notes Join Information
dbo assessment id 1 bigint 8
...
...
Рейтинг: 0 / 0
Слить много файлов в формате .csv в один Эксель файл
    #39841790
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roust_m,

в xslt-шаблон сразу после открывающего тэга ss:Table вставить
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
<ss:Row>
  <ss:Cell ss:MergeAcross="8" ss:StyleID="sH1">
    <ss:Data ss:Type="String">
      <xsl:value-of select="concat(@table_schema, '.', @table_name)" />
    </ss:Data>
  </ss:Cell>
</ss:Row>
<ss:Row>
  <ss:Cell ss:MergeAcross="8" ss:StyleID="sH1"><ss:Data ss:Type="String">&lt;&lt;&#x20;Go to main list</ss:Data></ss:Cell>
</ss:Row>
<ss:Row />
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Слить много файлов в формате .csv в один Эксель файл
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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