I'm trying to achieve a method whereby when a user upload a PDF document to a SQL Server database. The data would be uploaded instantly if network is available, but if there is no internet connection - the data would be stored somewhere else and be uploaded when internet connection is back. Please any idea how to achieve this?
Here is my code for the upload:
//CheckIfNetworkConnected( ) ;
Ping p = new Ping();
try
{
string host = "www.google.com";
//bool result = false;
PingReply reply = p.Send(host, 3000);
if (reply.Status == IPStatus.Success)
{
// Display form modelessly
pleaseWait.Show();
// Allow main UI thread to properly display please wait form.
Application.DoEvents();
using (SqlConnection con = new SqlConnection("Server=tcp:mycompany.database.windows.net,1433;Initial Catalog=DBmycompany;Persist Security Info=False;User ID=abubakarkabiru;Password=wordpass123#;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30"))
{
FileStream fStream = File.OpenRead(filepath);
byte[] contents = new byte[fStream.Length];
fStream.Read(contents, 0, (int)fStream.Length);
fStream.Close();
con.Open();
cmd = new SqlCommand("Insert into document values(#Staffname, #unit, #sites, #docname, #dateofreciept, #descriptions, #doc, #category, #housetype)", con);
if (textBox1.Visible == true)
{
cmd.Parameters.AddWithValue("#Unit", textBox1.Text);
cmd.Parameters.AddWithValue("#Staffname", textBox2.Text);
}
else
{
cmd.Parameters.AddWithValue("#Staffname", comboDesigner.SelectedItem.ToString());
cmd.Parameters.AddWithValue("#unit", comboUnit.SelectedItem.ToString());
}
cmd.Parameters.AddWithValue("#category", comboCategory.SelectedItem.ToString());
if (string.IsNullOrWhiteSpace(txtdocname.Text))
{
errorProvider1.SetError(txtdocname, "Compulsory");
}
else
{
cmd.Parameters.AddWithValue("#docname", string.IsNullOrWhiteSpace(txtdocname.Text));
}
cmd.Parameters.AddWithValue("#dateofreciept", dateTimePicker1.Value.ToShortDateString());
cmd.Parameters.AddWithValue("#doc", contents);
cmd.Parameters.AddWithValue("#sites", string.IsNullOrWhiteSpace(comboSites.ToString())
? (Object)comboSites.SelectedItem.ToString()
: (Object)DBNull.Value);
cmd.Parameters.AddWithValue("#housetype", string.IsNullOrWhiteSpace(comboHouseType.ToString())
? (Object)comboHouseType.SelectedItem.ToString()
: (Object)DBNull.Value);
cmd.Parameters.AddWithValue("#descriptions", string.IsNullOrWhiteSpace(txtDesc.Text)
? (object)txtDesc.Text
: (object)DBNull.Value);
var i = cmd.ExecuteNonQuery();
if (i > 0)
{
MessageBox.Show("Successful");
this.notifyIcon1.Icon = this.Icon;
this.notifyIcon1.ShowBalloonTip(600, "Upload Notice", "New Document has been Uploaded", ToolTipIcon.Info);
//notifyUpload();
}
con.Close();
}
pleaseWait.Hide();
cleaBoxes();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Related
I want to import data from Excel files into SQL Server. The size of the file is 22 MB and contains approximately 1 million rows, but I get the error timeout.
This is the code of my controller
[System.Web.Http.Route("UploadExcel")]
[System.Web.Http.HttpPost]
[RequestFormLimits(MultipartBodyLengthLimit = 409715200)]
[RequestSizeLimit(409715200)]
public string ExcelUpload()
{
string message = "";
HttpResponseMessage result = null;
var httpRequest = HttpContext.Current.Request;
using (AngularDBEntities objEntity = new AngularDBEntities())
{
if (httpRequest.Files.Count > 0)
{
HttpPostedFile file = httpRequest.Files[0];
Stream stream = file.InputStream;
IExcelDataReader reader = null;
if (file.FileName.EndsWith(".xls"))
{
reader = ExcelReaderFactory.CreateBinaryReader(stream);
}
else if (file.FileName.EndsWith(".xlsx"))
{
reader = ExcelReaderFactory.CreateOpenXmlReader(stream);
}
else
{
message = "This file format is not supported";
}
DataSet excelRecords = reader.AsDataSet();
reader.Close();
var finalRecords = excelRecords.Tables[0];
for (int i = 0; i < finalRecords.Rows.Count; i++)
{
UserDetail objUser = new UserDetail();
objUser.UserName = finalRecords.Rows[i][0].ToString();
objUser.EmailId = finalRecords.Rows[i][1].ToString();
objUser.Gender = finalRecords.Rows[i][2].ToString();
objUser.Address = finalRecords.Rows[i][3].ToString();
objUser.MobileNo = finalRecords.Rows[i][4].ToString();
objUser.PinCode = finalRecords.Rows[i][5].ToString();
objEntity.UserDetails.Add(objUser);
}
int output = objEntity.SaveChanges();
if (output > 0)
{
message = "Excel file has been successfully uploaded";
}
else
{
message = "Excel file uploaded failed";
}
}
else
{
result = Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
return message;
}
I added maxRequestLength="1048576" executionTimeout="999999" to the web.config file in the system.web section, and maxAllowedContentLength="1073741824" to security tag, but I am still facing this problem.
Knowing that when I upload small files, the data is added to the table
you can add all items in a list and finally use bulk insert. use can use Entity Framework Extensions.
EDIT :
If I hit directly the endpoint from the browser, the file is dowloaded correctly.
So I guess the problem is in the front and the way to create and save the file with the data received.
I have a java/spring boot application where I want to build an API endpoint that creates and returns a downloadable excel file. Here is my controller endpoint:
#GetMapping(path = "/informe/{informeDTO}")
public ResponseEntity<InputStreamResource> generarInforme(#PathVariable(value = "informeDTO") String informeDTOString) throws JsonParseException, JsonMappingException, IOException {
final InformeDTO informeDTO =
new ObjectMapper().readValue(informeDTOString, InformeDTO.class);
List<InformeDTO> listDatosinformeDTO = utilsService.getDatosInformeDTO(informeDTO);
for (InformeDTO informeDTO2 : listDatosinformeDTO) {
logger.debug(informeDTO2);
}
ByteArrayInputStream in = createReport(listDatosinformeDTO);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment; filename=IOPreport.xlsx");
return ResponseEntity.ok().headers(headers)
.contentType(
MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
.body(new InputStreamResource(in));
}
This is the angular controller :
function generarInformeIOP(){
InformesService.generarInformeIOP($scope.informeView.sociedad, $scope.informeView.area, $scope.informeView.epigrafe,
$scope.informeView.cuenta, $scope.informeView.status, $scope.informeView.organizationalUnit,
$scope.informeView.societyGL, $scope.informeView.calculationType, $scope.informeView.provincia, $scope.informeView.financialSegment,
$scope.informeView.loadDateFrom, $scope.informeView.loadDateTo, $scope.informeView.incomeDateFrom, $scope.informeView.incomeDateTo)
.then(
function(response)
{
var blob = new Blob([response.data], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"
});
saveAs(blob, "IOPreport.xlsx");
$scope.informeFunctionality.errorMessage = '';
},
function(errResponse)
{
console.log("ERROR: " + errResponse.data);
$scope.informeFunctionality.errorMessage = "Ha ocurrido un error inesperado: " + errResponse.data.error +
": " + errResponse.data.message;
}
)
}
And the service :
....
$http.get(urls.SERVICE_API + "informe/"+ angular.toJson(informeDTO)).then(
function(response) {
console.log("GenerarInformeIOP - success");
deferred.resolve(response);
}, function(errResponse) {
console.log("GenerarInformeIOP - error");
deferred.reject(errResponse);
});
...
The generation is successfull, the file is downloaded but I think it is corrupted because Excel can't open it.
Are there anything wrong?
EDIT (adding createReport) :
private ByteArrayInputStream createReport(List<InformeDTO> datosInforme) {
ByteArrayInputStream result =null;
try (Workbook workbook = new XSSFWorkbook(); ByteArrayOutputStream out = new ByteArrayOutputStream();) {
Set<String> columns = new LinkedHashSet<String>();
// Coumnas fijas
columns.add("Cuenta");
columns.add("Epigrafe");
columns.add("Descripcion");
columns.add("Total_Importe");
// Columnas dinamicas
/*
* Tedremos que recorrer todas las filas puesto que no sabremos si una traera
* menos periodos que otra de esta manera obtendremos todos los periodos
*/
for (InformeDTO informeDTO : datosInforme) {
for (Map.Entry<String, Double> entry : informeDTO.getTotalByPeriodoContable().entrySet()) {
columns.add(entry.getKey());
}
}
/*
* CreationHelper helps us create instances for various things like DataFormat,
* Hyperlink, RichTextString etc in a format (HSSF, XSSF) independent way
*/
// CreationHelper createHelper = workbook.getCreationHelper();
// Create a Sheet
Sheet sheet = workbook.createSheet("IOPReport");
// Create a Font for styling header cells
Font headerFont = workbook.createFont();
headerFont.setBold(true);
headerFont.setFontHeightInPoints((short) 14);
headerFont.setColor(IndexedColors.RED.getIndex());
// Create a CellStyle with the font
CellStyle headerCellStyle = workbook.createCellStyle();
headerCellStyle.setFont(headerFont);
// Create a Row
Row headerRow = sheet.createRow(0);
// Creating cells
int i = 0;
for (String value : columns) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(value);
cell.setCellStyle(headerCellStyle);
i++;
}
// Create Other rows and cells with employees data
int rowNum = 1;
int cellDynamicNum = 0;
for (InformeDTO informeDTO : datosInforme) {
Row row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(informeDTO.getCuenta());
row.createCell(1).setCellValue(informeDTO.getEpigrafe());
row.createCell(2).setCellValue(informeDTO.getDescripcion_epigrafe());
row.createCell(3).setCellValue("No Data");
cellDynamicNum = 4;
for (Map.Entry<String, Double> entry : informeDTO.getTotalByPeriodoContable().entrySet()) {
row.createCell(cellDynamicNum).setCellValue(entry.getValue());
cellDynamicNum++;
}
}
// Resize all columns to fit the content size
for (i = 0; i < columns.size(); i++) {
sheet.autoSizeColumn(i);
}
// Write the output to a file
workbook.write(out);
result = new ByteArrayInputStream(out.toByteArray());
out.close();
workbook.close();
} catch (Exception e) {
logger.debug("Excepcion en la creacion del report " + e);
}
return result;
}
Regards
When building the output here:
result = new ByteArrayInputStream(out.toByteArray());
The workbook is not saved into out until it is closed. So you need to change the order to:
workbook.close()
result = new ByteArrayInputStream(out.toByteArray());
Closing a ByteArrayOutputStream is not necessary but it's fine if you leave it.
I'm not sure why ResponseEntity<InputStreamResource> is used. I've another working solution which use byte-array ResponseEntity<byte[]>. Some of the code snippet are attached below:
After creating the workbook, write it to outputstream:
private final MediaType mediaType = MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
...
...
// at the end
ByteArrayOutputStream stream = new ByteArrayOutputStream();
workbook.write(stream);
return getDownload(stream.toByteArray(), filename, mediaType);
....
Download method:
public static ResponseEntity<byte[]> getDownload(byte[] content, String filename, MediaType mediaType) {
HttpHeaders headers = new HttpHeaders();
headers.setContentLength(content.length);
headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename);
headers.set(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);
headers.setContentType(mediaType);
return new ResponseEntity<>(content, headers, HttpStatus.OK);
}
Let me know if this works.
I resolved it adding the reponse type in the front call:
var config = { responseType: 'blob' };
$http.get(urls.SERVICE_API + "informe/"+ angular.toJson(informeDTO), config).then(
....
)
I have a process that must check the INBOX on GMail for a failure message, it's working except for the problem of the time it takes to connect and check the message, it takes about 1 minute, that is too much time.
My code:
public static SendResult sendingSuccess(final String email) {
SendResult result = new SendResult();
try {
Properties props = new Properties();
props.setProperty("mail.store.protocol", "imaps");
props.setProperty("mail.imap.com", "993");
props.setProperty("mail.imap.connectiontimeout", "5000");
props.setProperty("mail.imap.timeout", "5000");
Session session = Session.getDefaultInstance(props);
Store store = session.getStore("imaps");
store.connect("imap.googlemail.com", 993, GMAIL_USER, GMAIL_PASSWORD);
// Select and open folder
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);
// What to search for
SearchTerm searchTerm = new SearchTerm() {
private static final long serialVersionUID = -7187666524976851520L;
public boolean match(Message message) {
try {
String content = getContent(message);
boolean daemon = (message.getFrom()[0].toString()).contains("mailer-daemon#googlemail.com");
boolean failure = message.getSubject().contains("Failure");
boolean foundWarning = content.contains(email);
if (daemon && failure && foundWarning) {
return true;
}
} catch (Exception ex) {
ex.printStackTrace();
}
return false;
}
};
// Fetch unseen messages from inbox folder
Message[] messages = inbox.search(searchTerm);
// If there is no message then it's OK
result.setStatus(messages.length == 0);
result.setMessage(result.isStatus() ? "No failure message found for " + email : "Failure message found for " + email);
// Flag message as DELETED
for (Message message : messages) {
message.setFlag(Flags.Flag.DELETED, true);
}
// disconnect and close
inbox.close(false);
store.close();
} catch (Exception ex) {
result.setMessage(ex.getMessage());
ex.printStackTrace();
}
return result;
}
When I run this code to query the failure message it takes more than 1 minute to return the result to me.
======= Checking Gmail account for message failure! =====
Start...: 09:00:33
Finish..: 09:01:01
Result..: SendResult [status=true, message=No failure found for wrong.user#gmxexexex.net]
Is there any way to reduce this time?
The problem is most likely because you've written your own search term. JavaMail doesn't know how to translate your search term into an IMAP SEARCH request so it executes the search on the client, which requires downloading all the messages to the client to search there. Try this instead:
SearchTerm searchTerm = new AndTerm(new SearchTerm[] {
new FromStringTerm("mailer-daemon#googlemail.com"),
new SubjectTerm("Failure"),
new BodyTerm(email)
});
That will allow the search to be done by the IMAP server.
Pls How can I access sqlite database on the webserver in codename one? I can only use database API to access database on the device. In order to access this on the webserver I think is quite different thing. Pls I need a snippet code on this. Thanks
Use the code below, not tested and you may have to adjust it to suite your need. Leave a comment if there's an issue:
ConnectionRequest req = new ConnectionRequest() {
#Override
protected void handleException(Exception ex) {
//handle error
}
};
req.setUrl(YourURL);
req.setPost(true);
req.setHttpMethod("POST"); //Change to GET if necessary
req.setDuplicateSupported(true);
req.addArgument("argumentToSendThroughPostOrGet1", "value1");
req.addArgument("argumentToSendThroughPostOrGet2", "value2");
NetworkManager.getInstance().addToQueueAndWait(req);
if (req.getResponseCode() == 200) {
Map<String, Object> out = new HashMap<>();
Display.getInstance().invokeAndBlock(() -> {
JSONParser p = new JSONParser();
try (InputStreamReader r = new InputStreamReader(new ByteArrayInputStream(req.getResponseData()))) {
out.putAll(p.parseJSON(r));
} catch (IOException ex) {
//handle error
}
});
if (!out.isEmpty()) {
List<Map<String, Object>> responses = (List<Map<String, Object>>) out.get("response");
for (Object response : responses) {
Map res = (Map) response;
System.out.println(res.get("key"));
}
} else {
//handle error
}
} else {
//handle error
}
TEST JSON RESPONSE:
{
"response": [
{
"key": "I was returned",
}
]
}
EDIT:
To pass data from TextField:
req.addArgument("argumentToSendThroughPostOrGet1", myTextField.getText());
Based on your comment, you can read those arguments in PHP as simple as below:
$var1 = $_POST["argumentToSendThroughPostOrGet1"];
$var1 = $_GET["argumentToSendThroughPostOrGet1"]; // if GET method is used in Codename One
//Or use $_REQUEST which supports both methods but not advisable to be used for production
...
And you can use those variables in your php code normally.
Example of Usage with MySql Query:
class Connection {
function connect() {
$mysqli = mysqli_init();
$mysqli->real_connect("localhost", "username", "password", "databaseName") or die('Could not connect to database!');
$mysqli->query("SET NAMES 'UTF8'");
return $mysqli;
}
function close() {
mysqli_close($this->connect);
}
}
$connection = new Connection();
$mysqli = $connection->connect();
$mysqli->query("SELECT * FROM MyTable WHERE ColumnName LIKE '%$var1%' ORDER BY PrimaryKeyId ASC LIMIT 100");
I'm trying to get the count of unread email using google API, but not able. ANy help is highly appreciated. I'm not getting any error, but the count doesnt match the actual number shown in gmail.
try
{
String serviceAccountEmail = "xxx#developer.gserviceaccount.com";
var certificate = new X509Certificate2(#"C:\Projects\xxx\xyz\API Project-xxxxx.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
User = "xxx#gmail.com",
Scopes = new[] { Google.Apis.Gmail.v1.GmailService.Scope.GmailReadonly }
}.FromCertificate(certificate));
var gmailservice = new Google.Apis.Gmail.v1.GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "GoogleApi3",
});
try
{
List<Message> lst = ListMessages(gmailservice, "xxx#gmail.com", "IN:INBOX IS:UNREAD");
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
}
catch (Exception ex)
{
}
Just do: labels.get(id="INBOX") and it has those types of stats (how many messages in that label, how many are unread, and same for threads).
https://developers.google.com/gmail/api/v1/reference/users/labels/get
You can use the ListMessages method from the API example (included for completeness) for searching:
private static List<Message> ListMessages(GmailService service, String userId, String query)
{
List<Message> result = new List<Message>();
UsersResource.MessagesResource.ListRequest request = service.Users.Messages.List(userId);
request.Q = query;
do
{
try
{
ListMessagesResponse response = request.Execute();
result.AddRange(response.Messages);
request.PageToken = response.NextPageToken;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
} while (!String.IsNullOrEmpty(request.PageToken));
return result;
}
You can use this search method to find unread messages, for example like this:
List<Message> unreadMessageIDs = ListMessages(service, "me", "is:unread");
The q parameter (query) can be all kinds of stuff (it is the same as the gmail search bar on the top of the web interface), as documented here: https://support.google.com/mail/answer/7190?hl=en.
Note that you only a few parameters of the Message objects are set. If you want to retreive the messages you'll have to use GetMessage method from the api:
public static Message GetMessage(GmailService service, String userId, String messageId)
{
try
{
return service.Users.Messages.Get(userId, messageId).Execute();
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
return null;
}
I agree that the API is not straight forward and misses a lot of functionality.
Solution for .Net:
// Get UNREAD messages
public void getUnreadEmails(GmailService service)
{
UsersResource.MessagesResource.ListRequest Req_messages = service.Users.Messages.List("me");
// Filter by labels
Req_messages.LabelIds = new List<String>() { "INBOX", "UNREAD" };
// Get message list
IList<Message> messages = Req_messages.Execute().Messages;
if ((messages != null) && (messages.Count > 0))
{
foreach (Message List_msg in messages)
{
// Get message content
UsersResource.MessagesResource.GetRequest MsgReq = service.Users.Messages.Get("me", List_msg.Id);
Message msg = MsgReq.Execute();
Console.WriteLine(msg.Snippet);
Console.WriteLine("----------------------");
}
}
Console.Read();
}