I want to know that is there a chance to save Sql data to excel file without using Excel destination task and without using Excel connection in Script task.
If any answer please help me.
Thank You.
I found a way to import SQL data to Excel sheet without Excel task and excel connection of ADO.net or any SSIS Excel connections. I did it in a script task. I used documentformat.openxml package. I installed openxml package in NuGet manager. Then It didn't work showing some errors. When I opened the code reference was sowing some error. Then, I changed the reference path of the package manually and tried. It worked. Hope it would help someone.
Thank You,
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
namespace DataToExcel
{
class Program
{
static void Main(string[] args)
{
using (SpreadsheetDocument document = SpreadsheetDocument.Create(#"E:\Work\One.xlsx", SpreadsheetDocumentType.Workbook))
{
string connString = "Data Source=localhost;Initial Catalog=School;Integrated Security=True;";//Windows authentication
SqlConnection sqlConn = new SqlConnection(connString);
sqlConn.Open();
SqlCommand cmd = new SqlCommand("Test", sqlConn);
cmd.CommandType = CommandType.StoredProcedure;
DataTable dt = new DataTable();
dt.Load(cmd.ExecuteReader());
sqlConn.Close();
List<string> header = new List<string>();
int count = dt.Rows.Count;
foreach (DataColumn column in dt.Columns)
{
header.Add(column.ColumnName);
}
//Here is the code for Excel saving.
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
var sheetData = new SheetData();
worksheetPart.Worksheet = new Worksheet(sheetData);
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Sheet1" };
sheets.Append(sheet);
Row headerRow = new Row();
foreach (var item in header)
{
Cell cell = new Cell();
cell.DataType = CellValues.String;
cell.CellValue = new CellValue(item);
headerRow.AppendChild(cell);
}
sheetData.AppendChild(headerRow);
foreach (DataRow dsrow in dt.Rows)
{
Row newRow = new Row();
foreach (String col in header)
{
Cell cell = new Cell();
cell.DataType = CellValues.String;
cell.CellValue = new CellValue(dsrow[col].ToString());
newRow.AppendChild(cell);
}
sheetData.AppendChild(newRow);
}
workbookPart.Workbook.Save();
}
}
}
}
Related
This is a console application trying to print data from datatable to excel file using open XML lib. I have also provided datatable code for reference.
class ProgramCheck
{
private static void Main()
{
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(#"C:\Users\nilam\Desktop\Work\project\GeneratedExcel.xlsx", SpreadsheetDocumentType.Workbook);
WorkbookPart workbookPart = spreadsheetDocument.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
Sheet sheet = new Sheet()
{
Id = workbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "TestSheet2"
};
sheets.Append(sheet);
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
DataTable dt = Data.SampleData();
foreach (DataRow item in dt.Rows)
{
Row row = new Row();
for (int i = 0; i < item.ItemArray.Length; i++)
{
foreach (DataColumn itemCol in dt.Columns)
{
Columns col = new Columns();
Cell cell1 = new Cell()
{
CellValue = new CellValue(item[i].ToString()),
DataType = CellValues.String
};
col.Append(cell1);
Cell cell = new Cell()
{
CellValue = new CellValue(item[i].ToString()),
DataType = CellValues.String
};
row.Append(cell);
}
}
sheetData.Append(row);
}
workbookPart.Workbook.Save();
spreadsheetDocument.Close();
}
}
Code for row works fine, but when I try to loop through columns for heading, it does not append anything. I am using openXML to get data from the data table and output it into an excel file.
This is datatable (data.cs)
class Data
{
public static DataTable SampleData()
{
System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("Name");
dt.Columns.Add("Salary");
dt.Rows.Add("01", "Anis", "1000");
dt.Rows.Add("02", "AK", "2000");
dt.Rows.Add("03", "Mak", "3000");
return dt;
}
}
I have looked at the documentation of openXML but could not find anything so far.
[![enter image description here][1]][1]
enter code here
[1]: https://i.stack.imgur.com/EaPLh.png
I solved this...this is for someone who needs help. This code can be more refined you are welcome to do so and paste it.
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(#"C:\Users\nilam\Desktop\Work\project\GeneratedExcel.xlsx", SpreadsheetDocumentType.Workbook);
WorkbookPart workbookPart = spreadsheetDocument.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
Sheet sheet = new Sheet()
{
Id = workbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "TestSheet2"
};
sheets.Append(sheet);
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
DataTable dt = Data.SampleData();
//this is for Columns heading
Row rowHeading = new Row();
for (int j = 0; j < dt.Columns.Count; j++)
{
Cell cell1 = new Cell()
{
CellValue = new CellValue(dt.Columns[j].ColumnName.ToString()),
DataType = CellValues.String
};
rowHeading.Append(cell1);
}
sheetData.Append(rowHeading);
//this is for row content
foreach (DataRow item in dt.Rows)
{
Row row = new Row();
for (int i = 0; i < item.ItemArray.Length; i++)
{
Cell cell = new Cell()
{
CellValue = new CellValue(item[i].ToString()),
DataType = CellValues.String
};
row.Append(cell);
}
sheetData.Append(row);
}
workbookPart.Workbook.Save();
spreadsheetDocument.Close();
}
I need to export data from database to excel document using spring.
But when I download from controller document I get message that is currupted file or wrong extension.
private static final String EXCEL_FILE_NAME = "UserExcelExport.xlsx";
#GetMapping("/download")
public void download(HttpServletResponse response) throws Exception {
List<User> users = userService.getUsers();
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet("All Users List");
Row header = sheet.createRow(0);
header.createCell(0).setCellValue("Username");
header.createCell(1).setCellValue("First name");
header.createCell(2).setCellValue("Last name");
header.createCell(3).setCellValue("E-mail");
int rowNum = 1;
for (User user : users) {
Row row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(user.getUsername());
row.createCell(1).setCellValue(user.getFirstName());
row.createCell(2).setCellValue(user.getLastName());
row.createCell(3).setCellValue(user.getEMail());
}
response.setHeader("Content-disposition", "attachment; filename=" + EXCEL_FILE_NAME);
workbook.write(response.getOutputStream());
}
It is missing the content-type:
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
Also use XSSFWorkbook to generate an .xlsx file:
XSSFWorkbook wb = new XSSFWorkbook();
Edit~~~~
Here is a full example that works, I use SpringBoot 2.2.2 and POI 3.15.
#GetMapping(value = "/main/export")
public void export(HttpServletResponse response) throws Exception {
// user list
List<UserDto> users = new ArrayList<>();
users.add(new UserDto(1L, "user1"));
users.add(new UserDto(2L, "user2"));
XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("All Users List");
Row header = sheet.createRow(0);
header.createCell(0).setCellValue("Username");
header.createCell(1).setCellValue("First name");
header.createCell(2).setCellValue("Last name");
header.createCell(3).setCellValue("E-mail");
int rowNum = 1;
for (UserDto user : users) {
Row aRow = sheet.createRow(rowNum++);
aRow.createCell(0).setCellValue(user.getId());
aRow.createCell(1).setCellValue(user.getName());
}
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("content-disposition", "attachment; filename=myfile.xlsx");
workbook.write(response.getOutputStream());
}
I have same problm.
I tried using you suggestion.
#GetMapping("/download")
public void download(HttpServletResponse response) throws Exception {
List<User> users = userService.getUsers();
XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("All Users List");
Row header = sheet.createRow(0);
header.createCell(0).setCellValue("Username");
header.createCell(1).setCellValue("First name");
header.createCell(2).setCellValue("Last name");
header.createCell(3).setCellValue("E-mail");
int rowNum = 1;
for (User user : users) {
Row aRow = sheet.createRow(rowNum++);
aRow.createCell(0).setCellValue(user.getUsername());
aRow.createCell(1).setCellValue(user.getFirstName());
aRow.createCell(2).setCellValue(user.getLastName());
aRow.createCell(3).setCellValue(user.getEMail());
}
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("content-disposition", "attachment; filename=myfile.xlsx");
workbook.write(response.getOutputStream());
}
But when I download from controller document i get this:
I'm facing of difficulties to change a files into CSV and save it into local environment. How can I achieve this? Try to look around but seem like not what I'm looking for.
I'm running on SharePoint 2010. Before this, this code only grab data from SharePoint and turn it into xlsx and update it into our web.
private static void GenerateSPGroupUsersReport() //
{
Log("Generate Sharepoint Group Users Report");
DataSet dsSecurityReport = new DataSet();
string ConnectedWebURL = ConfigurationManager.AppSettings["SPGroupUsersWebURL"];
//string[] strURL = ConnectedWebURL.Split(';');
DataTable dTblSPGroupUser = new DataTable();
dTblSPGroupUser.Columns.Add("SiteURL", typeof(string));
dTblSPGroupUser.Columns.Add("SharepointGroup", typeof(string));
dTblSPGroupUser.Columns.Add("User", typeof(string));
// Hafees add 10/22/2019
dTblSPGroupUser.Columns.Add("UserLanID", typeof(string));
dTblSPGroupUser.Columns.Add("Email", typeof(string));
SPSite site = new SPSite(ConnectedWebURL);
SPWebApplication webApp = site.WebApplication;
foreach (SPSite s in webApp.Sites)
{
SPGroupCollection groupCol = s.RootWeb.SiteGroups;
foreach (SPGroup group in groupCol)
{
// Hafees include group.Users, user.Email
foreach (SPUser user in group.Users)
{
dTblSPGroupUser.Rows.Add(s.Url, group.Name, user.Name, user.LoginName, user.Email);
}
//bool contains = dTblSPGroupUser.AsEnumerable().Any(rowC => group.Name == rowC.Field<string>("SharepointGroup"));
//if (!contains)
//{
// foreach (SPUser user in group.Users)
// {
// dTblSPGroupUser.Rows.Add(s.Url, group.Name, user.Name);
// }
//}
}
}
DataSet dsSPGroup = new DataSet();
dsSPGroup.Tables.Add(dTblSPGroupUser);
SaveIntoSPLibrary(site, dsSPGroup, "GroupUsers_" + ConnectedWebURL.Replace("http://", "").Replace("https://", "").Replace(":", "-").Trim());
Log("Generate Sharepoint Group Users Report Complete");
}
// This is where I generate the group of user report.
private static void SaveIntoSPLibrary(SPSite site, DataSet ds, string fileName)
{
string UIResourceServerRelativeWebURL = ConfigurationManager.AppSettings["UIResourceServerRelativeWebURL"];
using (SPWeb web = site.OpenWeb(UIResourceServerRelativeWebURL))
{
byte[] byteArray = GenerateExcelFile(ds);
string CustomReportLibrary = ConfigurationManager.AppSettings["CustomReportLibrary"];
string strFileName = String.Format(fileName + ".{0}.xlsx", DateTime.Today.ToString("yyyyMMdd"));
Log("Saving into SP Library. " + CustomReportLibrary + strFileName);
web.AllowUnsafeUpdates = true;
SPFile file = web.Files.Add(CustomReportLibrary + strFileName, byteArray, true);
file.Item["Year"] = DateTime.Now.ToString("yyyy");
file.Item["Month"] = string.Format("{0}. {1}", DateTime.Now.Month, DateTime.Now.ToString("MMMM"));
file.Item.Update();
file.Update();
web.AllowUnsafeUpdates = false;
}
}
// This is where the files save into xlsx and update it into SharePoint Library.
I try to do a copy of SaveIntoLibrary with abit of modification, I change to CSV files and create a new configurationManager which it will point into my local directory. But seem I'm wrong at somewhere. The files still didn't get into my local directory. Please advice.
You should export the DataTable report data to local CSV,
Check the code in this thread, this will output the csv file so you could save to your local.
var dataTable = GetData();
StringBuilder builder = new StringBuilder();
List<string> columnNames = new List<string>();
List<string> rows = new List<string>();
foreach (DataColumn column in dataTable.Columns)
{
columnNames.Add(column.ColumnName);
}
builder.Append(string.Join(",", columnNames.ToArray())).Append("\n");
foreach (DataRow row in dataTable.Rows)
{
List<string> currentRow = new List<string>();
foreach (DataColumn column in dataTable.Columns)
{
object item = row[column];
currentRow.Add(item.ToString());
}
rows.Add(string.Join(",", currentRow.ToArray()));
}
builder.Append(string.Join("\n", rows.ToArray()));
Response.Clear();
Response.ContentType = "text/csv";
Response.AddHeader("Content-Disposition", "attachment;filename=myfilename.csv");
Response.Write(builder.ToString());
Response.End();
My #Test method takes input from an excel work book. The input values are categorized in several work sheets. The total number of input values are more than 50. How to pass this excel data with several sheets to the #Test method as i can't define all the parameters in the #Test method as arguments. Please help.
You can use System.Data.OleDb and use it in someway like this....
public static DataSet actual_read(string filename)
{
var conn = string.Format(#"Provider=Microsoft.ACE.OLEDB.12.0; data source={0}; Extended Properties=Excel 12.0;", filename);
DataSet allSheetVal = new DataSet();
string[] sheets = GetExcelsheetNames(conn);
//bool isspace = false;
using (OleDbConnection con = new OleDbConnection(conn))
{
con.Open();
foreach (string sheet in sheets)
{
string[] spsheet = sheet.Split(' ');
int toSub = (spsheet.Count() > 1) ? 2 : 1;
string sheetName = sheet;
if (sheetName[sheetName.Length - toSub] != '$')
{
if (toSub == 2)
{
sheetName = sheetName.Substring(0, (sheetName.Length - 1));
sheetName += "$'";
}
else
sheetName += '$';
}
var adapter = new OleDbDataAdapter("select * from [" + sheetName + "]", con);
var ds = new DataSet();
adapter.Fill(ds, sheetName);
allSheetVal.Tables.Add(ds.Tables[sheetName].Copy());
}
con.Close();
}
return allSheetVal;
}
so that it will return a DataSet then you can read it....(note each sheet is treated as a table in this execution)
I've read a bunch of stuff on the web about how to get at cell data using the OpenXML API. But there's really not much out there that's particularly straightforward. Most seems to be about writing to SpreadsheetML, not reading... but even that doesn't help much.
I've got a spreadsheet that has a table in it. I know what the table name is, and I can find out what sheet it's on, and what columns are in the table. But I can't figure out how to get a collection of rows back that contain the data in the table.
I've got this to load the document and get a handle to the workbook:
SpreadsheetDocument document = SpreadsheetDocument.Open("file.xlsx", false);
WorkbookPart workbook = document.WorkbookPart;
I've got this to find the table/sheet:
Table table = null;
foreach (Sheet sheet in workbook.Workbook.GetFirstChild<Sheets>())
{
WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheet.Id);
foreach (TableDefinitionPart tableDefinitionPart in worksheetPart.TableDefinitionParts)
{
if (tableDefinitionPart.Table.DisplayName == this._tableName)
{
table = tableDefinitionPart.Table;
break;
}
}
}
And I can iterate over the columns in the table by foreaching over table.TableColumns.
To read an Excel 2007/2010 spreadsheet with OpenXML API is really easy. Somehow even simpler than using OleDB as we always did as quick & dirty solution. Moreover it's not just simple but verbose, I think to put all the code here isn't useful if it has to be commented and explained too so I'll write just a summary and I'll link a good article. Read this article on MSDN, it explain how to read XLSX documents in a very easy way.
Just to summarize you'll do this:
Open the SpreadsheetDocument with SpreadsheetDocument.Open.
Get the Sheet you need with a LINQ query from the WorkbookPart of the document.
Get (finally!) the WorksheetPart (the object you need) using the Id of the Sheet.
In code, stripping comments and error handling:
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, false))
{
Sheet sheet = document.WorkbookPart.Workbook
.Descendants<Sheet>()
.Where(s => s.Name == sheetName)
.FirstOrDefault();
WorksheetPart sheetPart =
(WorksheetPart)(document.WorkbookPart.GetPartById(theSheet.Id));
}
Now (but inside the using!) what you have to do is just to read a cell value:
Cell cell = sheetPart.Worksheet.Descendants<Cell>().
Where(c => c.CellReference == addressName).FirstOrDefault();
If you have to enumerate the rows (and they are a lot) you have first to obtain a reference to the SheetData object:
SheetData sheetData = sheetPart.Worksheet.Elements<SheetData>().First();
Now you can ask for all the rows and cells:
foreach (Row row in sheetData.Elements<Row>())
{
foreach (Cell cell in row.Elements<Cell>())
{
string text = cell.CellValue.Text;
// Do something with the cell value
}
}
To simply enumerate a normal spreadsheet you can use Descendants<Row>() of the WorksheetPart object.
If you need more resources about OpenXML take a look at OpenXML Developer, it contains a lot of good tutorials.
There are probably many better ways to code this up, but I slapped this together because I needed it, so hopefully it will help some others.
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Packaging;
private static DataTable genericExcelTable(FileInfo fileName)
{
DataTable dataTable = new DataTable();
try
{
using (SpreadsheetDocument doc = SpreadsheetDocument.Open(fileName.FullName, false))
{
Workbook wkb = doc.WorkbookPart.Workbook;
Sheet wks = wkb.Descendants<Sheet>().FirstOrDefault();
SharedStringTable sst = wkb.WorkbookPart.SharedStringTablePart.SharedStringTable;
List<SharedStringItem> allSSI = sst.Descendants<SharedStringItem>().ToList<SharedStringItem>();
WorksheetPart wksp = (WorksheetPart)doc.WorkbookPart.GetPartById(wks.Id);
foreach (TableDefinitionPart tdp in wksp.TableDefinitionParts)
{
QueryTablePart qtp = tdp.QueryTableParts.FirstOrDefault<QueryTablePart>();
Table excelTable = tdp.Table;
int colcounter = 0;
foreach (TableColumn col in excelTable.TableColumns)
{
DataColumn dcol = dataTable.Columns.Add(col.Name);
dcol.SetOrdinal(colcounter);
colcounter++;
}
SheetData data = wksp.Worksheet.Elements<SheetData>().First();
foreach (DocumentFormat.OpenXml.Spreadsheet.Row row in data)
{
if (isInTable(row.Descendants<Cell>().FirstOrDefault(), excelTable.Reference, true))
{
int cellcount = 0;
DataRow dataRow = dataTable.NewRow();
foreach (Cell cell in row.Elements<Cell>())
{
if (cell.DataType != null && cell.DataType.InnerText == "s")
{
dataRow[cellcount] = allSSI[int.Parse(cell.CellValue.InnerText)].InnerText;
}
else
{
dataRow[cellcount] = cell.CellValue.Text;
}
cellcount++;
}
dataTable.Rows.Add(dataRow);
}
}
}
}
//do whatever you want with the DataTable
return dataTable;
}
catch (Exception ex)
{
//handle an error
return dataTable;
}
}
private static Tuple<int, int> returnCellReference(string cellRef)
{
int startIndex = cellRef.IndexOfAny("0123456789".ToCharArray());
string column = cellRef.Substring(0, startIndex);
int row = Int32.Parse(cellRef.Substring(startIndex));
return new Tuple<int,int>(TextToNumber(column), row);
}
private static int TextToNumber(string text)
{
return text
.Select(c => c - 'A' + 1)
.Aggregate((sum, next) => sum * 26 + next);
}
private static bool isInTable(Cell testCell, string tableRef, bool headerRow){
Tuple<int, int> cellRef = returnCellReference(testCell.CellReference.ToString());
if (tableRef.Contains(":"))
{
int header = 0;
if (headerRow)
{
header = 1;
}
string[] tableExtremes = tableRef.Split(':');
Tuple<int, int> startCell = returnCellReference(tableExtremes[0]);
Tuple<int, int> endCell = returnCellReference(tableExtremes[1]);
if (cellRef.Item1 >= startCell.Item1
&& cellRef.Item1 <= endCell.Item1
&& cellRef.Item2 >= startCell.Item2 + header
&& cellRef.Item2 <= endCell.Item2) { return true; }
else { return false; }
}
else if (cellRef.Equals(returnCellReference(tableRef)))
{
return true;
}
else
{
return false;
}
}