How to read excel File from ASHX page? - javascript

Hi i have uploaded file to one amazon s3 server,how can i read excel file and want to send excel data to database.
my code is
<script type="text/javascript">
var obj = null;
$(function () {
$('#fileupload').fileupload({
replaceFileInput: false,
formData: function (form) {
return [{ name: "name1", value: "value1" }, { name: "name2", value: "value2"}];
$('#btnGo').click(function () {
obj.submit();
});
});
</script>
And my ashx page, where i need to read excel data
public class AjaxFileHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
var file = context.Request.Files[0];
string fileName=fileName = Guid.NewGuid().ToString() + file.FileName;
Stream streamContentFile = context.Request.Files[0].InputStream;
var iFileSize = context.Request.Files[0].ContentLength;
byte[] data = new byte[iFileSize];
int bytes_read = 0;
while (bytes_read < iFileSize)
{
int bytes_read_this_iteration = streamContentFile.Read(data, bytes_read, iFileSize - bytes_read);
streamContentFile.Close();
streamContentFile.Dispose();
CommonBLL.UploadTemporaryFilesToS3Bucket(fileName, data);
//Here i need to read excel code can you provide how to do that pleas
}

I would use open source libraries for excel, EPPlus (xslx) or NPOI (xls). They are very easy to use, and I am using EPPlus for numerous excel imports / exports and it's working great. These libraries have no external dependancies, and you can use it on server side.

you need two things:
a Driver that allows code to read Excel content
access to this file
a query over excel data
In this sample:
I use ACE (Microsoft Access Database Engine) driver, that must be installed on the server
the file is in App_Data folder (in your case the file should be rached CommonBLL library, i suppose)
the query is an UPDATE query; you can replace with a SELECT or INSERT query, using common DB SNippets.
string fileName= Server.MapPath( "~/App_Data/MyFile.xls");
string sheetName= "Sheet1";
string connString = string.Format(
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 8.0;HDR=No'"
, fileName);
string command = string.Format("UPDATE [{0}${1}:{1}] SET F1='{2}'", sheetName,cellName, cellValue);
using (OleDbConnection oledbConn = new OleDbConnection(connString))
{
oledbConn.Open();
using (OleDbCommand cmd = new OleDbCommand(command, oledbConn))
cmd.ExecuteNonQuery();
oledbConn.Close();
}

Related

How do I write a LZ compressed string to text file using JXA?

I am trying to write a JXA script in Apple Script Editor, that compresses a string using the LZ algorithm and writes it to a text (JSON) file:
var story = "Once upon a time in Silicon Valley..."
var storyC = LZString.compress(story)
var data_to_write = "{\x22test\x22\x20:\x20\x22"+storyC+"\x22}"
app.displayAlert(data_to_write)
var desktopString = app.pathTo("desktop").toString()
var file = `${desktopString}/test.json`
writeTextToFile(data_to_write, file, true)
Everything works, except that the LZ compressed string is just transformed to a set of "?" by the time it reaches the output file, test.json.
It should look like:
{"test" : "㲃냆੠Њޱᐈ攀렒삶퓲ٔ쀛䳂䨀푖㢈Ӱນꀀ"}
Instead it looks like:
{"test" : "????????????????????"}
I have a feeling the conversion is happening in the app.write command used by the writeTextToFile() function (which I pulled from an example in Apple's Mac Automation Scripting Guide):
var app = Application.currentApplication()
app.includeStandardAdditions = true
function writeTextToFile(text, file, overwriteExistingContent) {
try {
// Convert the file to a string
var fileString = file.toString()
// Open the file for writing
var openedFile = app.openForAccess(Path(fileString), { writePermission: true })
// Clear the file if content should be overwritten
if (overwriteExistingContent) {
app.setEof(openedFile, { to: 0 })
}
// Write the new content to the file
app.write(text, { to: openedFile, startingAt: app.getEof(openedFile) })
// Close the file
app.closeAccess(openedFile)
// Return a boolean indicating that writing was successful
return true
}
catch(error) {
try {
// Close the file
app.closeAccess(file)
}
catch(error) {
// Report the error is closing failed
console.log(`Couldn't close file: ${error}`)
}
// Return a boolean indicating that writing was successful
return false
}
}
Is there a substitute command for app.write that maintains the LZ compressed string / a better way to accomplish what I am trying to do?
In addition, I am using the readFile() function (also from the Scripting Guide) to load the LZ string back into the script:
function readFile(file) {
// Convert the file to a string
var fileString = file.toString()
// Read the file and return its contents
return app.read(Path(fileString))
}
But rather than returning:
{"test" : "㲃냆੠Њޱᐈ攀렒삶퓲ٔ쀛䳂䨀푖㢈Ӱນꀀ"}
It is returning:
"{\"test\" : \"㲃냆੠Њޱᐈ攀렒삶퓲ٔ쀛䳂䨀푖㢈Ӱນꀀ\"}"
Does anybody know a fix for this too?
I know that it is possible to use Cocoa in JXA scripts, so maybe the solution lies therein?
I am just getting to grips with JavaScript so I'll admit trying to grasp Objective-C or Swift is way beyond me right now.
I look forward to any solutions and/or pointers that you might be able to provide me. Thanks in advance!
After some further Googl'ing, I came across these two posts:
How can I write UTF-8 files using JavaScript for Mac Automation?
read file as class utf8
I have thus altered my script accordingly.
writeTextToFile() now looks like:
function writeTextToFile(text, file) {
// source: https://stackoverflow.com/a/44293869/11616368
var nsStr = $.NSString.alloc.initWithUTF8String(text)
var nsPath = $(file).stringByStandardizingPath
var successBool = nsStr.writeToFileAtomicallyEncodingError(nsPath, false, $.NSUTF8StringEncoding, null)
if (!successBool) {
throw new Error("function writeFile ERROR:\nWrite to File FAILED for:\n" + file)
}
return successBool
};
While readFile() looks like:
ObjC.import('Foundation')
const readFile = function (path, encoding) {
// source: https://github.com/JXA-Cookbook/JXA-Cookbook/issues/25#issuecomment-271204038
pathString = path.toString()
!encoding && (encoding = $.NSUTF8StringEncoding)
const fm = $.NSFileManager.defaultManager
const data = fm.contentsAtPath(pathString)
const str = $.NSString.alloc.initWithDataEncoding(data, encoding)
return ObjC.unwrap(str)
};
Both use Objective-C to overcome app.write and app.read's inability to handle UTF-8.

Download an xlsx file with reactJS: Excel can not open file

I'm trying to download an xlsx file with reactJS but i'm receiving this message when i try to open my file after download:
"Excel can not open file 'file.xlsx' because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the file format"
Here's the frontend code:
const REST_DOWNLOAD_URL = REST_URL + '/token';
Rest.ajaxPromise('GET', REST_DOWNLOAD_URL).then(function (res) {
var FILE_URL = "/supermarket/token/" + res;
Rest.ajaxPromise('GET', FILE_URL).then(function (my_file) {
let blob = new Blob([my_file._body], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' });
if (navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, 'file.xlsx');
} else {
let link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.setAttribute('download', 'file.xlsx');
document.body.appendChild(link);
link.download = '';
link.click();
document.body.removeChild(link);
}
});
});
Why am i getting this error? Please somebody help me, i'm stuck on this for 3 weeks
[EDIT 1]
The file that i'm trying to download is build on backend, basically i get the values on database and use the Apache poi workbook to create the excel sheet. I will show you the mainly parts of the code:
1) This method is called by frontend on the first GET requisition of frontend and aims to prepare the file before the download. Is very simple, just create a token (buildToken()) and associate a temp file with this token (createTempFile(randomBackendToken)). The temp file is filled with what i get on my database (createFile(os))
#RequestMapping(value = "/token", method = RequestMethod.GET)
public String returnToken() throws IOException {
String randomBackendToken = tokenGenerator.buildToken();
OutputStream os = tokenGenerator.createTempFile(randomBackendToken);
tokenGenerator.createFile(os);
return randomBackendToken;
}
2) The method where i create the temp file:
public OutputStream createTempFile(String randomBackendToken) throws IOException {
OutputStream os = null;
File file = File.createTempFile(randomBackendToken, ".xlsx");
os = new FileOutputStream(file);
return os;
}
3) The method where i receive the empty temp file and fills with my data on database:
public void createFile(OutputStream os) throws IOException {
List<Supermakets> supermarkets = service.findAllSupermarkets();
Workbook workbook = writeExcel.createSheet(supermarkets);
workbook.write(os);
IOUtils.closeQuietly(os);
}
4) My WriteExcel Class that build the xlsx file:
private static String[] columns = {"Code", "Name", "Type"};
public Workbook createSheet(List<Supermarket> supermarkets) throws IOException {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("file");
[....]
// Row for Header
Row headerRow = sheet.createRow(0);
// Header
for (int col = 0; col < columns.length; col++) {
Cell cell = headerRow.createCell(col);
cell.setCellValue(columns[col]);
cell.setCellStyle(headerCellStyle);
}
//Content
int rowIdx = 1;
for (Supermarket supermarket : supermarkets) {
Row row = sheet.createRow(rowIdx++);
row.createCell(0).setCellValue(supermarket.getCode());
row.createCell(1).setCellValue(supermarket.getName());
row.createCell(2).setCellValue(supermarket.getType());
}
return workbook;
}
So, this all above is just for the first GET requisition. I make another one and the method below holds the second requisition. I just verify the token that the frontend returns for me and them, based on the validation, i allow the download of the file that i created on the previous step:
public void export(#PathVariable(value = "frontendToken") String frontendToken, HttpServletResponse response) throws IOException {
if (StringUtils.isNotBlank(frontendToken)) {
String tmpdir = System.getProperty("java.io.tmpdir");
File folder = new File(tmpdir);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
boolean fileIsValid = tokenGenerator.validateToken(frontendToken, listOfFiles[i]);
if (fileIsValid) {
InputStream input = new FileInputStream(listOfFiles[i]);
OutputStream output = response.getOutputStream();
int data = input.read();
while (data != -1) {
output.write(data);
data = input.read();
}
input.close();
output.flush();
output.close();
String mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
response.setContentType(mimeType);
listOfFiles[i].delete();
}
}
}
}
}
And that's all that i'm doing. Can't find what's wrong or what i'm missing. When i press F12 on my navigator to see the response of the request, shows for me something encoded, like:
PK#SM_rels/.rels­’ÁjÃ0†_ÅèÞ8í`ŒQ·—2èmŒî4[ILbËØÚ–½ýÌ.[Kì($}ÿÒv?‡I½Q.ž£uÓ‚¢hÙùØx>=¬î#ÁèpâH"Ã~·}¢
Any suspicions of what can be?
guys!
The problem was: my binary data was being converted for string by javascript and this was breaking my excel file. i solved my problem converting my binary data on backend to text and then on frontend i make the inverse. The following links helped me:
java convert inputStream to base64 string
Creating a Blob from a base64 string in JavaScript
Thank you for everyone that tried to help. I hope my question can help others

Download selected files in knockout js

I need to download the selected files in a grid on download button click. I am using knokout.js and web api
Using the below given response I was able to download a single file
self.DownloadDoc = function () {
window.location.assign("http://localhost:8092/api/Document/GetResponse?id=" + self.selectedDocuments()[0]);
self.selectedDocuments.removeAll();
self.bindDocuments();
};
I tried looping this window.location.assign() code using for loop,but as it is synchronous call,its downloading only one file.
Html part
<span>Download</span><small></small>
Web Api code
[HttpGet]
public HttpResponseMessage GetResponse(string id)
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
List<DocumentsModel> documents = _service.GetDocumentContent(Convert.ToInt32(id));
byte[] fileBytes = documents.FirstOrDefault().FileContent;
System.Net.Http.Headers.MediaTypeHeaderValue mediaType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
if (fileBytes != null)
response.Content = new ByteArrayContent(fileBytes);
response.Content.Headers.ContentType = mediaType;
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = documents.FirstOrDefault().FileLeafRef;
return response;
}
this part self.selectedDocuments()[0], looks like it will force download always only of first document.
Not sure what is your structure and output of selectedDocuments(),
for example, if it outputs array, with fileID nodes, maybe you should try with this:
<div data-bind="foreach: self.selectedDocuments()">
<span>Download</span><small></small>
</div>
then, you will have to pass param in function:
self.DownloadDoc = function (fileID) {
window.location.assign("http://localhost:8092/api/Document/GetResponse?id=" + fileID);
self.selectedDocuments.removeAll();
self.bindDocuments();
};

How can show document file in iframe when i get the file name from database?

How can show document file in iframe when i get the file name from database?My database table name is File and my viewmodel is MyFileModel.
public ActionResult Create(HttpPostedFileBase file)
{
try
{
if (ModelState.IsValid)
{
db.Files.Add(new File()
{
FileName = Path.GetFileName(file.FileName)
});
db.SaveChanges();
}
}
catch (Exception)
{
var error = "Sorry not save";
}
return Content("");
}
public FileStreamResult GetPDF()
{
var file = db.Files.Single(s => s.Id == 1);
FileStream fs = new FileStream(Server.MapPath(file.FileName), FileMode.Open, FileAccess.Read);
return File(fs, "application/pdf");
//return View(Server.MapPath("~/File/SegmentAdd.txt"));
//return File(fs,"text/plain");
}
<div id="frame">
<iframe src="#Url.Action("GetPDF","Home")" width="900px" height="500px"></iframe>
</div>
`
The answer which I am posting is all on an assumption, I do not have clear picture of your solution.
If you are not saving a physical file try to save it in a folder and then save the name in the DB OR try to save the entire path in the DB.
Method 1 :
If you are saving the file in a folder say File best way is to add a key in the web.config(.config file which is at the root) as follows
<add key="FilePath" value= "~/File/"/>
and then modify your C# code as follows
public FileStreamResult GetPDF()
{
var file = db.Files.Single(s => s.Id == 1);
string fileName = file.FileName;
string filePath = ConfigurationManager.AppSettings["FilePath"] + fileName;
FileStream fs = new FileStream(Server.MapPath(filePath), FileMode.Open, FileAccess.Read);
return File(fs,"text/plain"); // "text/plain" if your file content-type is text file
//return View(Server.MapPath("~/File/SegmentAdd.txt"));
//return File(fs,"text/plain");
}
Method 2 :
If you are saving the entire path then it makes coding much more simpler and you need not change the code you have written, just go ahead with the same.
Hope this would help you.
I think the way the pdf will open is dependent on the browser that the user uses.
You probably need something like: https://pdfobject.com/.
Good luck!

Upload file from Javascript to Google Cloud Endpoint

I'm creating a web app using only HTML5 + Javascript + jQueryMobile and I wanted to upload a file to a Google App Engine web application using a Google Cloud Endpoint, also created by me.
As I control both sides, I can (and want to) create the simplest interaction possible.
As for the Endpoint, I thought of creating a method like this:
#ApiMethod(
name = "uploadFile",
path = "upload_file",
httpMethod = HttpMethod.POST
)
public void uploadFile(File file) {
//process the file
}
This File class could contain a field fileData of type Blob, or byte[] or something like that, repersenting the file data... Something like:
public class File {
private String fileName;
private long fileSize;
private Blob fileData;
//getters and setters
}
So the first question would be: what's the most suitable type for this field fileData?
And, taking into account the type selected for the field, how could I create the necessary POST request for that endpoint method form Javascript/jQuery?
Basically I need to create a POST request to http://myappid.appspot.com/_ah/api/files/v1/upload_file adding the File object in the POST data.
Note: I'm sorry I haven't tried anything for the Javascript code because I'm not familiar at all with this technologies, so I'd appreciate any help...
Edit: The answer below targes python version of AppEngine
It is a common demand with no clear solution. Till now, gae-init-upload is a demonstration of how you can achieve that with AppEngine and CoffeeScript. Worth having a look, CoffeeScript is being compiled into JavaScript in case you are not familiar.
The JavaScript solution you are looking for is under
/main/static/src/coffee/common/upload.coffee
I eventually used this code in my AMD Javascript application. I'm sorry I cannot explain it too much because I've written a big amount of code since I wrote this project, and as you can see I didn't comment the code properly (fail!!), anyway maybe you can get some ideas...
Note that there's something about getting navigator position because I wanted to store the location where the file was uploaded from, but it's not necessary at all!
Controller.js
uploadFile: function(request, render) {
var self = this;
var file = $("#file").get(0).files[0];
var reader = new FileReader();
reader.onload = function (evt) {
var upload = {
provider: self.folder.provider,
folderIdentifier: self.folder.id,
fileName: file.name,
fileSize: file.size,
base64Data: btoa(evt.target.result),
location: {
latitude: self.position.coords.latitude,
longitude: self.position.coords.longitude
}
}
var uploadFilePromise = self.connector.uploadFile(self.sessionToken.token, upload);
uploadFilePromise.done(function (file) {
render("file", {
result: "DONE",
file: file
});
});
uploadFilePromise.fail(function (error) {
render("file", {
result: "FAIL"
});
});
}
navigator.geolocation.getCurrentPosition(function(position) {
self.position = position;
reader.readAsBinaryString(file);
});
}
Connector.js
uploadFile: function (sessionToken, upload) {
var self = this;
var promise = new Promise();
gapi.client.load('upload', 'v1', function() {
var request = gapi.client.upload.uploadFile({
session_token: sessionToken,
resource: upload
});
request.execute(function(response) {
if (response.error) {
promise.reject(response.error);
}
else {
var file = File.create(response.result.provider,
response.result.type,
response.result.identifier,
response.result.name,
response.result.description,
response.result.created,
response.result.size,
response.result.link,
{
latitude: response.result.location.latitude,
longitude: response.result.location.longitude
});
promise.resolve(file);
}
});
}, self.api);
return promise;
}
Endpoint.java
#Api(name="upload")
public class UploadEndpoint {
#ApiMethod(
name = "uploadFile",
path = "upload_file",
httpMethod = HttpMethod.POST
)
public File uploadFile (
#Named("session_token") String token,
Upload upload) throws InternalServerErrorException {
File file = new UploadController().uploadFile(token, upload);
return file;
}
}

Categories