I had a code in MVC which successfully exports out the Excel file but how do I add the password into the Excel file?
My code:
public ActionResult Report(string id)
{
LocalReport lr = new LocalReport();
string path = Path.Combine(Server.MapPath("~/Report"), "ReportStateArea.rdlc");
if (System.IO.File.Exists(path))
{
lr.ReportPath = path;
}
else
{
return View("Index");
}
List<StateArea> cm = new List<StateArea>();
using (myDatabaseEntities dc = new myDatabaseEntities())
{
cm = dc.StateAreas.ToList();
}
ReportDataSource rd = new ReportDataSource("MyDataset", cm);
lr.DataSources.Add(rd);
string reportType = id ;
string mimeType;
string encoding;
string fileNameExtension;
string deviceInfo =
"<DeviceInfo>" +
" <OutputFormat>" + id + "</OutputFormat>" +
" <PageWidth>8.5in</PageWidth>" +
" <PageHeight>11in</PageHeight>" +
" <MarginTop>0.5in</MarginTop>" +
" <MarginLeft>1in</MarginLeft>" +
" <MarginRight>1in</MarginRight>" +
" <MarginBottom>0.5in</MarginBottom>" +
"</DeviceInfo>";
Warning[] warnings;
string[] streams;
byte[] renderedBytes;
renderedBytes = lr.Render(
reportType,
deviceInfo,
out mimeType,
out encoding,
out fileNameExtension,
out streams,
out warnings);
return File(renderedBytes, mimeType);
}
You can use FileStream Class to write renderedBytes on a file.
Dim strExcelFile As String = "C:\YourPathTo\ExcelFile.xls"
Dim fs As New FileStream(strExcelFile, FileMode.Create)
fs.Write(renderedBytes, 0, renderedBytes.Length)
fs.Close()
fs.Dispose()
Then use Microsoft.Office.Interop.Excel.dll to add a password to an existing workbook:
Dim appExcel As Excel.Application
Dim wbExcel As Excel.Workbook
appExcel = New Excel.Application
wbExcel = appExcel.Workbooks.Open(strExcelFile)
wbExcel.Password = "YourPassword"
appExcel.DisplayAlerts = False
wbExcel.SaveAs(strExcelFile)
appExcel.DisplayAlerts = True
wbExcel.Close()
I used DisplayAlerts to suppress prompts and alert messages while using SaveAs to overwrite existing file; when a message requires a response, Microsoft Excel chooses the default response.
My code is in VB.NET but you can simply translate it in C#.
Related
I'm using Excel to create a form that is linked to another sheet that acts as a database.
This is my form (worksheet's name : "Form"):
And this is part of the database (worksheet's name: "Data"):
Right now it connects using a VBA script that is activated using the "save" button (green). Here's parts of the script:
Private Sub destBook()
setFormBook
If (destinationBook Is Nothing) Then
Dim file As String
file = ThisWorkbook.Sheets("_options").Cells(2, 26).Value //"path/to/the/database/file.xlsx"
If (IsEmpty(file)) Then
ThisWorkbook.Sheets("_options").Select
ThisWorkbook.Sheets("_options").Cells(2, 26).Select
Dim m As VbMsgBoxResult
m = MsgBox("")
Else
Set destinationBook = Workbooks.Open(file)
End If
End If
End Sub
Sub SaveClick()
Dim dataIdx As Integer
dataIdx = GetIdx()
If (dataIdx >= 2) Then
destBook
If (hasLock() = False) Then
WarnNoLock
closeDst
Else
Dim mappingRng As Range: Set mappingRng = ThisWorkbook.Sheets("_mappings").Range("F2:F71")
Dim rowIdx As Integer
For rowIdx = 1 To mappingRng.Rows.count
Dim FormRange As Range
Set FormRange = mappingRng.Cells(RowIndex:=rowIdx, ColumnIndex:=1)
If FormRange <> "" Then
Dim dataCol As Integer
Dim newValue As String
dataCol = mappingRng.Cells(RowIndex:=rowIdx, ColumnIndex:=2)
newValue = ThisWorkbook.Sheets("Form").Range(FormRange).Value
destinationBook.Sheets("Data").Cells(dataIdx, dataCol).Value = newValue
End If
Next
' refresh
Application.CalculateFull
End If
' close & save
closeDst
End If
End Sub
My question : Instead of saving/re-writing the data (Form) to another Excel file (Data), is it possible to save/re-write the data (Form) to a Google Sheet document ?
My guess would be to use the sharing link, but not sure how to make it works.
you can import JsonConverter.bas into your project (Open VBA Editor, Alt + F11; File > Import File) from https://github.com/VBA-tools/VBA-JSON/releases
and make table in your excel sheet, input this code to your module
Sub ConnectSheets()
Set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP.6.0") 'To use POST http Request
'Get data table as JSON
tableData = JsonConverter.ConvertToJson(Sheets("Page1").ListObjects("Table1").Range.Value)
' 'Create All Json to Send
Data = "{""dataReq"": " & vbNewLine & tableData & vbNewLine & ", " & vbNewLine & " ""fname"":""pasteData""}"
Debug.Print Data
'Define the google URL
myurl = "https://script.google.com/macros/s/AKfycbzE0nm-Jz2yE4IWc7OB_ter8NrNKBL9SXuxi6cG74FeUpwCx6T9tFZyPd13dRxgaqEm/exec"
xmlhttp.Open "POST", myurl, False 'define method to use
xmlhttp.Send Data 'execute call
sGetResult = xmlhttp.ResponseText 'read response
Debug.Print sGetResult 'view response
End Sub
and put code to your google sheet, apply as webapp
function doPost(request = {}) {
const { parameter, postData: { contents, type } = {} } = request; //request data
const { dataReq = {} } = JSON.parse(contents); //content
const { fname = {} } = JSON.parse(contents); //function name
const response = {
status: "function not found: " + fname, // prepare response in function not found
data2: dataReq
}
switch (fname) { //function selection
case 'pasteData':
var output = JSON.stringify(pasteData(dataReq)) //call function with data, name and type from request
break
default:
var output = JSON.stringify(response)
break
}
return ContentService.createTextOutput(output).setMimeType(ContentService.MimeType.JSON); //response to frontend
}
function pasteData(dataReq) {
const id = '1wtGM5QL0LwIYJoU9joOO31n_kBbJJJHRFaKtIdwWOeU'; //id of Google Sheet
var sheet = SpreadsheetApp.openById(id).getSheetByName('Page1'); //sheet
sheet.clear(); //delete data
sheet.getRange(1, 1, dataReq.length, dataReq[0].length).setValues(dataReq); // paste new data
return "Numbers of sheets added: "+ dataReq.length; //return a response
}
I have a column "Product_Decription" in MySQL database, and its data type is Text.
When user updates the column through UI, there may exists breakline. When my function "Download all product description" exports the data to Excel file, the breakline disappears. How can i maintain the text formatting which similar to the database?
Download function as follows:
Dim forDownloadGV As New GridView()
forDownloadGV.DataSource = ""
forDownloadGV.DataBind()
Dim myConnection As MySqlConnection
Dim myDataAdapter As MySqlDataAdapter
Dim myDataset As DataSet
Dim strSQL As String
myConnection = New MySqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("for_Read").ConnectionString)
myConnection.Close()
myConnection.Open()
strSQL = "SELECT REPLACE(REPLACE(`Product_Desription`, char(13), '<br/>'), CHAR(10), '<br/>') as 'Description'from `Products`"
myDataAdapter = New MySqlDataAdapter(strSQL, myConnection)
myDataset = New DataSet()
myDataAdapter.Fill(myDataset, "Products")
forDownloadGV.DataSource = myDataset
forDownloadGV.DataBind()
Response.Clear()
Response.Buffer = True
Response.AddHeader("content-disposition", "attachment;filename=Products.xls")
Response.Charset = ""
Response.ContentType = "application/vnd.ms-excel"
Dim sw As New StringWriter()
Dim hw As New HtmlTextWriter(sw)
For i As Integer = 0 To forDownloadGV.Rows.Count - 1
'Apply text style to each Row
forDownloadGV.Rows(i).Attributes.Add("class", "textmode")
Next
forDownloadGV.RenderControl(hw)
'style to format numbers to string
Dim style As String = "<style> .textmode{mso-number-format: \#;}</style>"
Response.Write(style)
Response.Output.Write(sw.ToString())
Response.Flush()
Response.End()
I have tried replacing to but the Excel file when downloaded still does not maintain the original text formatting.
Any help? Should the formatting be done at the Select statement?
if it helps anyone. Below will be the solution.
Dim forDownloadGV As New GridView()
forDownloadGV.DataSource = ""
forDownloadGV.DataBind()
Dim myConnection As MySqlConnection
Dim myDataAdapter As MySqlDataAdapter
Dim myDataset As DataSet
Dim strSQL As String
myConnection = New MySqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("for_Read").ConnectionString)
myConnection.Close()
myConnection.Open()
strSQL = "SELECT REPLACE(REPLACE(`Product_Desription`, char(13), '<br>'), CHAR(10), '<br>') as 'Description'from `Products`"
myDataAdapter = New MySqlDataAdapter(strSQL, myConnection)
myDataset = New DataSet()
myDataAdapter.Fill(myDataset, "Products")
forDownloadGV.DataSource = myDataset
forDownloadGV.DataBind()
Response.Clear()
Response.Buffer = True
Response.AddHeader("content-disposition", "attachment;filename=Products.xls")
Response.Charset = ""
Response.ContentType = "application/vnd.ms-excel"
Dim sw As New StringWriter()
Dim hw As New HtmlTextWriter(sw)
hw.AddAttribute("xmlns:x", "urn:schemas-microsoft-com:office:excel") ' optional'
hw.RenderBeginTag(HtmlTextWriterTag.Html)
hw.RenderBeginTag(HtmlTextWriterTag.Head)
hw.RenderBeginTag(HtmlTextWriterTag.Style)
hw.Write("br {mso-data-placement:same-cell;}")
hw.RenderEndTag() ' /Style'
hw.RenderEndTag() ' /Head'
hw.RenderBeginTag(HtmlTextWriterTag.Body)
forDownloadGV.RenderControl(hw)
hw.RenderEndTag() ' /Body'
hw.RenderEndTag() ' /Html'
Response.Write(HttpUtility.HtmlDecode(sw.ToString)) ' turns <br/> back into <br/>'
Response.Flush()
Response.End()
I had a working function call the Docusign SOAP API and now all of the sudden its not working. I get the error "The data could not be converted" when I call the CreateEnvelopeFromTemplatesAndForms method. Here is my code.
Dim _userName As String = ""
Dim _apiUrl As String = "https://demo.docusign.net/api/3.0/api.asmx"
Dim _accountId As String = "d90f6802-fa06-42b4-ac3b-5959c3905002"
Dim _password As String = "WWWxyz123"
Dim _email As String = "JGarland#etgroup.net"
Dim _integratorKey As String = "ETGX-1f61c95b-06bd-400b-9604-f247fda0238c"
Sub Main()
'GetSignatureSpot(Nothing)
'GetPDF()
'GetCertificate()
'Exit Sub
_userName = "[" + _integratorKey + "]"
_userName = _userName & _email
Dim _apiClient As DocuSign.DSAPIServiceSoapClient = New DocuSign.DSAPIServiceSoapClient("DSAPIServiceSoap", _apiUrl)
_apiClient.ClientCredentials.UserName.UserName = _userName
_apiClient.ClientCredentials.UserName.Password = _password
Dim envelopeInfo As DocuSign.EnvelopeInformation = New DocuSign.EnvelopeInformation()
envelopeInfo.AccountId = _accountId
envelopeInfo.EmailBlurb = "Please Sign Your Loan Documents"
envelopeInfo.Subject = "Please Sign Your Loan Documents"
'Recipients
Dim recipient1 As DocuSign.Recipient = New DocuSign.Recipient()
recipient1.UserName = "John Doe"
recipient1.Email = "Support#etgroup.net"
recipient1.Type = DocuSign.RecipientTypeCode.Signer
recipient1.RoutingOrder = 1
recipient1.RoutingOrderSpecified = True
recipient1.RoleName = "Borrower 1"
recipient1.ID = "1"
Dim recipient2 As DocuSign.Recipient = New DocuSign.Recipient()
recipient2.UserName = "Jane Doe"
recipient2.Email = "JGarland#etgroup.net"
recipient2.Type = DocuSign.RecipientTypeCode.Signer
recipient2.RoutingOrder = 2
recipient2.RoutingOrderSpecified = True
recipient2.RoleName = "Borrower 2"
recipient2.ID = "2"
Dim signers(1) As DocuSign.Recipient
signers(0) = recipient1
signers(1) = recipient2
'Create draft with all the composite template information
Dim status As DocuSign.EnvelopeStatus
Dim compositTemplate(1) As DocuSign.CompositeTemplate
Dim template As DocuSign.CompositeTemplate
Dim template2 As DocuSign.CompositeTemplate
'Template 1
template = CreateTemplate(1, "Attorney Selection Notice", "F364E20C-D0E6-4735-89E2-8891424BA364", signers, "AttorneySelection.pdf")
compositTemplate(0) = template
'Template 2
template2 = CreateTemplate(2, "Notice of No Oral", "F5A536C3-81AB-4C32-B56A-9F764624C3C4", signers, "NoticeOral.pdf")
compositTemplate(1) = template2
status = _apiClient.CreateEnvelopeFromTemplatesAndForms(envelopeInfo, compositTemplate, True)
End Sub
Private Function CreateTemplate(sequence As Integer, templateName As String, templateID As String, signers() As DocuSign.Recipient, docPath As String) As DocuSign.CompositeTemplate
Dim template As DocuSign.CompositeTemplate = New DocuSign.CompositeTemplate()
'Server Template
Dim serverTemplate As DocuSign.ServerTemplate = New DocuSign.ServerTemplate()
serverTemplate.Sequence = sequence
serverTemplate.TemplateID = templateID
Dim serverTemplates(0) As DocuSign.ServerTemplate
serverTemplates(0) = serverTemplate
template.ServerTemplates = serverTemplates
'Inline Template
Dim inlineTemplate As DocuSign.InlineTemplate = New DocuSign.InlineTemplate()
inlineTemplate.Sequence = "1"
inlineTemplate.Envelope = New DocuSign.Envelope()
inlineTemplate.Envelope.Recipients = signers
inlineTemplate.Envelope.AccountId = _accountId
Dim inlineTemplates(0) As DocuSign.InlineTemplate
inlineTemplates(0) = inlineTemplate
template.InlineTemplates = inlineTemplates
'Document.
template.Document = New DocuSign.Document()
template.Document.ID = "1"
template.Document.Name = ""
template.Document.PDFBytes = System.IO.File.ReadAllBytes(path:=docPath)
template.Document.FileExtension = "pdf"
Return template
End Function
It looks like there were issues with the DocuSign Demo environment (server) recently, according to the DocuSign Trust Center. This is most likely what was causing your issues.
These issues are currently resolved and your envelopes should be working again now. For reference, this is the DocuSign Trust Center with monitoring on the DEMO environment:
https://trust.docusign.com/system-status/demo
I have created a windows application using list.asmx (getlistitems method) to download documents from a document library which is on another server. I am able to access document names, url, etc. When I use following code to download a file, it is returning html of the login page as content of each file that I am trying to download.
Any thoughts?
Dim spAuthentication As New Authentication()
spAuthentication.Url = authenticationWSAddress
spAuthentication.CookieContainer = New CookieContainer()
Dim spLists As New Lists()
spLists.Url = listWSAddress
'Try to login to SharePoint site with Form based authentication
Dim loginResult As LoginResult = spAuthentication.Login(userName, password)
Dim cookie As New Cookie()
'If login is successfull
If loginResult.ErrorCode = LoginErrorCode.NoError Then
'Get the cookie collection from the authenticatin web service
Dim cookies As CookieCollection = spAuthentication.CookieContainer.GetCookies(New Uri(spAuthentication.Url))
'Get the specific cookie which contains the security token
cookie = cookies(loginResult.CookieName)
'Initialize the cookie container of the list web service
spLists.CookieContainer = New CookieContainer()
'set the cookie of list web service to the authenticatio cookie
spLists.CookieContainer.Add(cookie)
'Dim responseNode As XmlNode = spLists.GetListCollection()
'response = responseNode.InnerXml
Dim query As String = "<mylistitems><Query><Where><Eq><FieldRef Name='FileDirRef' /><Value Type='Url'>DocLib/Property Documents/BELASERA AT FULTON (lax10027)/Master Meter Invoices</Value></Eq></Where></Query><QueryOptions><ViewAttributes Scope='RecursiveAll' IncludeRootFolder='False' /><IncludeAttachmentUrls>TRUE</IncludeAttachmentUrls><ViewFields><FieldRef Name='EncodedAbsUrl'/></ViewFields></QueryOptions></mylistitems>"
Dim doc As New XmlDocument()
doc.LoadXml(query)
Dim dt As DataTable = Nothing
Dim queryNode As XmlNode = doc.SelectSingleNode("//Query")
Dim viewNode As XmlNode = doc.SelectSingleNode("//ViewFields")
Dim optionNode As XmlNode = doc.SelectSingleNode("//QueryOptions")
Dim retNode As XmlNode = spLists.GetListItems("DocLib", String.Empty, queryNode, viewNode, String.Empty, optionNode, Nothing)
Dim ds As New DataSet()
Using sr As New StringReader(retNode.OuterXml)
ds.ReadXml(sr)
End Using
If ds.Tables("Row") IsNot Nothing AndAlso ds.Tables("Row").Rows.Count > 0 Then
dt = ds.Tables("Row").Copy()
For Each myrow As DataRow In dt.Rows
' myrow.Item(0) contains url of the document
If myrow.Item(0) IsNot Nothing AndAlso myrow.Item(0) <> "" Then
DownLoadAttachmentold(myrow.Item("ows_EncodedAbsUrl"), RemoveLookupID(myrow.Item("ows_FileLeafRef")))
End If
Next
End If
Public Shared Sub DownLoadAttachment(ByVal strURL As String, ByVal strFileName As String)
Dim myWebClient As New WebClient()
Dim DestinationFolder As String = "C:\\DownLoads\\"
Form2.RTBStatus.AppendText("Downloading File " + strFileName + " from " + strURL + " .......")
' The DownloadFile() method downloads the Web resource and saves it into the current file-system folder.
myWebClient.DownloadFile(strURL, DestinationFolder + strFileName)
'Form2.RTBStatus.AppendText("Successfully Downloaded file ""{0}"" from ""{1}""", "C:\\DownLoads\\" + strFileName, strURL)
Form2.RTBStatus.AppendText((ControlChars.Cr + "Downloaded file saved in the following file system folder:" + ControlChars.Cr + ControlChars.Tab + DestinationFolder))
End Sub
DownloadAttachment also needs to make (forms-based) authenticated HTTP requests.
An example in C# below:
request = (HttpWebRequest)WebRequest.Create(strURL);
request.Credentials = System.Net.CredentialCache.DefaultCredentials;//adapt for your FBA
request.AllowWriteStreamBuffering = false;
response = (HttpWebResponse)request.GetResponse();
Stream s = response.GetResponseStream();
FileStream fs = new FileStream(#"C:\DownLoads\"+strFileName, FileMode.Create);
Hi
I am using an ASP.NET application and producing a report in excel page with .csv extension. However I would like to produce it with .xlsx etension.
The code I am currently using is as follows:
Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnSubmit.Click
Dim sql As String
Dim strLine As String = ""
Dim attachment As String = "attachment; filename=PTW.csv"
m_sBranch = ddlBranches.SelectedValue
m_sRegion = ddlAreas.SelectedValue
Dim cnn As SqlConnection = New SqlConnection("Server=XYZ;Database=abc;Trusted_Connection=yes;")
HttpContext.Current.Response.AddHeader("content-disposition", attachment)
HttpContext.Current.Response.ContentType = "text/csv"
cnn.Open()
sql = GetReportSql(m_sBranch, m_sRegion)
Dim cmd As SqlCommand = New SqlCommand(sql, cnn)
Dim dr As SqlDataReader
dr = cmd.ExecuteReader()
HttpContext.Current.Response.Write("PTW JOBS - EXPORTED ON " + DateTime.Now)
For i = 0 To dr.FieldCount - 1
strLine = strLine & dr.GetName(i).ToString & ","
Next
HttpContext.Current.Response.Write(strLine)
Dim sb As StringBuilder = New StringBuilder()
Dim temp As String = ""
While dr.Read()
For i = 0 To dr.FieldCount - 1
temp = temp & dr.GetValue(i)
temp = temp.Replace(",", " ")
sb.Append(temp & ",")
temp = ""
Next
sb.AppendLine()
strLine = ""
End While
HttpContext.Current.Response.Write(sb.ToString())
End Sub
Any help will be highly appreciated. Thanks.
Look into the OpenXML SDK:
I understand that my example doesn't convert .csv files, but it will steer you in the right direction.
http://msdn.microsoft.com/en-us/library/bb448854(office.14).aspx
I've used it in asp.net to create xlsx documents on the fly, streamed directly to the web client:
public static System.IO.MemoryStream ConvertToExcel(DataSet ds)
{
System.IO.MemoryStream stream = new System.IO.MemoryStream();
using (SpreadsheetDocument package = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook, true))
{
package.AddWorkbookPart();
package.WorkbookPart.Workbook = new Workbook();
package.WorkbookPart.AddNewPart<WorksheetPart>();
if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
{
DataTable tbl = ds.Tables[0];
SheetData xlSheetData = new SheetData();
foreach (DataRow row in tbl.Rows)
{
Row xlRow = new Row();
foreach (DataColumn col in tbl.Columns)
{
object cellData = row[col];
Cell xlCell = null;
if (cellData != null)
{
xlCell = new Cell(new InlineString(new DocumentFormat.OpenXml.Spreadsheet.Text(cellData.ToString()))) { DataType = CellValues.InlineString };
}
else
{
xlCell = new Cell(new InlineString(new DocumentFormat.OpenXml.Spreadsheet.Text(String.Empty))) { DataType = CellValues.InlineString };
}
xlRow.Append(xlCell);
}
xlSheetData.Append(xlRow);
}
package.WorkbookPart.WorksheetParts.First().Worksheet = new Worksheet(xlSheetData);
package.WorkbookPart.WorksheetParts.First().Worksheet.Save();
// create the worksheet to workbook relation
package.WorkbookPart.Workbook.AppendChild(new Sheets());
package.WorkbookPart.Workbook.GetFirstChild<Sheets>().AppendChild(new Sheet()
{
Id = package.WorkbookPart.GetIdOfPart(package.WorkbookPart.WorksheetParts.First()),
SheetId = 1,
Name = "Sheet1"
});
package.WorkbookPart.Workbook.Save();
}
}
return stream;
}
Shariful, from what I've read (not tried yet), I believe the best method is to set your HTTP Response headers as outlined here.
In short, the key seems to be setting the content-disposition header to "attachment".
e.g.:
Content-Disposition: attachment; filename=<file name.ext>
Sorry that I haven't tested this, but in my searching for something closely related, almost every place I went suggests to use this method in order to force download dialog.