iFactory thông báo tuyển dụng lập trình viên


VIỆC LÀM CÔNG TY START-UP

1. Street Smart

Bạn có biết Street Smart là gì không?

STREET SMART

Nếu chưa biết thì chỉ cần lên Google là xong ngay thôi!

Thực tế thì các kỹ sư Street Smart có thu nhập và cơ hội thăng tiến cao hơn nhiều lần mặt bằng chung.

Để có Street Smart cách duy nhất là phải ở “Street”. Không ai ngồi nhà mà có thể hiểu rõ chuyện đường phố.

Start-up là một trong những môi trường tốt nhất để đào tạo Street Smart. Vì ở đó bạn phải xoay sở và tự làm mọi việc.

Nếu bạn nghe điều này mà thấy “sôi máu” hãy nộp đơn để gia nhập đôi ngũ iFactory.

2. Về iFactory

iFactory là một start up công nghệ. Chúng tôi đeo đuổi việc ứng dụng công nghệ vào các giải pháp quản trị nhà máy sản xuất.

Sau 3 năm phát triển, iFactory đã phát triển thành công các giải pháp:

  • Phần mềm quản trị sản xuất toàn diện trên Desktop và Mobile.
  • Phần mềm thống kê chuyên dụng cho sản xuất.
  • Phần mềm kết nối dữ liệu với hầu hết các thiết bị điện tử.
  • Công nghệ truyền dữ liệu Zigbee.
  • Công nghệ đo lường chính xác bằng camera.
  • Công nghệ kiểm tra lỗi bề mặt chính xác bằng camera.

3. Mô tả công việc

  • Năm đầu tiên lập trình C# – WPF.
  • Năm thứ 2 trở đi phát triển nghề nghiệp phù hợp với khả năng.

4. Chế độ phúc lợi

  • Môi trường làm việc mở.
  • Đồng nghiệp thân thiện, gắn bó và hỗ trợ.
  • Lương khởi điểm thoả thuận.
  • Thu nhập phát triển theo doanh thu công ty.
  • Chỗ ở ngay tại khu công nghệ phần mềm ITP.

5.Yêu cầu:

  • Kỹ sư IT mới tốt nghiệp hoặc sẵn sàng đi làm toàn thời gian.
  • Kỹ sư đã có 1~2 năm kinh nghiệm.
  • Không yêu cầu tiếng Anh nhưng cần biết tự nghiên cứu trên mạng.
  • Năng lực phù hợp với công việc IT.
  • Đam mê lập trình và công nghệ.
  • Thái độ làm việc nghiêm túc.

6. Thông tin nộp đơn

  • Email: ta@ifactory.vn (Mr. Toàn)
  • Nhận hồ sơ đến hết ngày 30.09.2018

[Quốc Khánh 02/09] Danh sách 9 bạn được tặng 14 khóa học Online


🔥🔥🔥Tin Nóng Hổi! Vừa Thổi Vừa Đọc!🔥🔥🔥
Sau hơn 1 tuần gay cấn, lọc hơn 300 Email gửi về có cùng ngày sinh với Đại Lễ 02/09. Thầy chốt danh sách 9 bạn được tặng toàn bộ các Khóa học online của Thầy, với tổng thời lượng các khóa học lên tới 264 giờ.
Thầy sẽ gửi danh sách mã kích hoạt qua Email cho 9 bạn may mắn!

Danh sách khóa học được tặng:


Các khóa học vẫn đang được giới thiệu trên http://communityuni.com/. Để được tư vấn miễn phí lộ trình Học Lập Trình các bạn hãy vào https://www.facebook.com/communityuni/ để Inbox nhé

Hiện tại Mua 2 cuốn sách Mobile [176k] vẫn còn chính sách tặng 1 Khóa Android Online:
Link đăng ký mua sách: 🌏https://goo.gl/UBneJr

Thầy Thanh.

[Quốc Khánh 02/09] Đăng ký nhận tặng 14 khoá học


📣📣📣Mừng Quốc Khánh 02/09📣📣📣

9 bạn đầu tiên có ngày sinh nhật 02/09 trên Chứng Minh Nhân hoặc Thẻ Căn Cước sẽ được tặng 14 khóa học với tổng thời lượng lên tới 264 giờ học liên tục:

Không có văn bản thay thế tự động nào.

👉Các Em đăng ký vào email: 💌[duythanhcse@gmail.com]
Yêu cầu định dạng Email:
1) Tiêu đề: [Đại Lễ 02/09] Đăng ký nhận tặng 14 khóa học
2) Nội dung: Cung cấp nội dung phù hợp (cách hành văn) + hình chụp của Chứng Minh Nhân Dân hoặc Thẻ Căn Cước có ngày sinh trùng với Đại Lễ 02/09.

Thầy sẽ chọn lọc 9 bạn may mắn đầu tiên và có định dạng email gửi phù hợp.

🔥🔥🔥Lưu ý: Sự kiện sẽ bắt đầu từ ngày 23/08/2018-> hết ngày 02/09/2018. Sau ngày 03/09/2018 Thầy sẽ gửi tặng khóa học qua Email.🔥🔥🔥

Thông tin chi tiết đề cương các khóa học tại đây:
🌏http://communityuni.com/

Ngoài ra trong sự kiện này những bạn không may mắn có ngày sinh trùng Đại Lễ 02/09. Thầy sẽ cung cấp khóa học theo các hướng lập trình:
😍A) Gói lập trình .NET chuyên nghiệp gồm chuỗi 5 môn học:
C++ -> Cấu trúc dữ liệu và Giải thuật -> C# Cơ bản -> C# nâng cao -> tăng tốc thiết kế phần mềm với LINQ
Tổng học phí: 500k💰
😍B) Gói lập trình Java chuyên nghiệp gồm chuỗi 4 khóa học:
C++ -> Cấu trúc dữ liệu và Giải thuật -> Java Cơ bản -> Java nâng cao
Tổng học phí: 400k💰
😍C) Gói Lập trình Mobile chuyên nghiệp gồm chuỗi 5 khóa học:
C++ -> Cấu trúc dữ liệu và Giải thuật -> Java Cơ bản -> Kotlin -> Android
Tổng học phí: 500k💰
😍D) Gói Lập trình full-stack chuyên nghiệp gồm chuỗi 9 khóa học:
C++ -> Cấu trúc dữ liệu và Giải thuật -> Java Cơ bản -> Kotlin -> Android -> C# cơ bản -> C# nâng cao -> tăng tốc thiết kết phần mềm với LINQ -> Webservice RESTful API

Tổng học phí: 900k💰
😍E) Mua 2 cuốn sách Mobile[176k] được tặng Khóa Android Online:
Link đăng ký: 🌏https://goo.gl/UBneJr

Để được tư vấn kỹ càng hơn, hãy LIKE và FOLLOW :
🌏https://www.facebook.com/communityuni/

🔥🔥🔥🔥🔥🔥🔥🔥🔥
Thông tin chuyển khoản khi mua các khóa học:
-STK: 0101146302
-Ngân hàng Đông á, chi nhánh gò vấp
-Chủ TK: Trần Duy Thanh
Chuyển Banking xong chát thông báo cho Thầy là Ok
🔥🔥🔥🔥🔥🔥🔥🔥🔥

Thầy Thanh

Tổng hợp học liệu các khóa Online


Dear all
vì nhiều em không biết tải học liệu trên hệ thống và nhiều bạn cần để tham khảo. Nên Thầy cung cấp giáo trình, Slide, source code của toàn bộ 15 khóa học Online đang publish:
👉1) Giải đề thi Excel: http://www.mediafire.com/file/5agwyapc35cvbmi/communityuni.com%23%23%23Excel-Slides_BaiTap_DeThi.rar
👉2) C++: http://www.mediafire.com/file/992rxcbfq13oatc/communityuni.com%23%23%23C++-giaotrinh-sourcecode-slide.rar/file
👉3) CTDL & Giải thuật: http://www.mediafire.com/file/3qjtpgaa9a53o3t/communityuni.com%23%23%23CTDL_GT_Tap1.rar
👉4) C# cơ bản:
slide:http://www.mediafire.com/file/51vvkmm01qey5ze/communityuni.com%23%23%23Slides_LapTrinhC%23Trong5Tuan_CoBan.rar
code:http://www.mediafire.com/file/sb7kl39ro2trk1r/communityuni.com%23%23%23Sourecode_LapTrinhC%23Trong5Tuan_CoBan.rar
👉5) C# nâng cao:
Slide:http://www.mediafire.com/file/2abat1cxkm6sbkc/communityuni.com%23%23%23Slides_LapTrinhC%23Trong5Tuan_NangCao.rar
Code:http://www.mediafire.com/file/z01oxplzogc5jzy/communityuni.com%23%23%23Sourecode_LaptrinhC%235tuan_NangCao.rar
CSDL:http://www.mediafire.com/file/xrzrpzns2vqz247/communityuni.com%23%23%23CSDL_LapTrinhC%235tuan_NangCao.rar
👉6) LINQ:
Slide:http://www.mediafire.com/file/dgurkd7woav65xw/communityuni.com%23%23%23Slides_ThanhThaoLinQ6Tuan.rar
Code:http://www.mediafire.com/file/yntczuh8xyc0kyx/communityuni.com%23%23%23SourceCode_CSDL_ThanhThaoLinQ6Tuan.rar
CSDL:http://www.mediafire.com/file/70pl6v0fd2tep25/communityuni.com%23%23%23CSDL_LINQ.rar
Bài tập bổ sung: http://www.mediafire.com/file/j06qjl6bm0mmi49/communityuni.com%23%23%23Exercises_LINQ.rar
👉7) Java cơ bản:
Slide:http://www.mediafire.com/file/qg6agcpeqd4588y/communityuni.com%23%23%23Slides_MonLapTrinhJavaTrong4Tuan.rar
Code:http://www.mediafire.com/file/6dgmdta865a7p8t/communityuni.com%23%23%23SourceCode_JavaCoban.rar
Bài tập bổ sung:http://www.mediafire.com/file/0b9d4bn0f6s1zn5/communityuni.com%23%23%23Final_java1_Exercise.docx
👉8) Java nâng cao:
Slide-Code:http://www.mediafire.com/file/rl6ddvri3ci2dz9/communityuni.com%23%23%23HocLieuJavaNangCao.rar
Bài tập bổ sung:http://www.mediafire.com/file/xvwa8z9n1r0j5tn/communityuni.com%23%23%23Final_Java2_Excercise.docx
👉9) Android cơ bản:
Slide:http://www.mediafire.com/file/8ah35kt5u3rs4ju/communityuni.com%23%23%23Slides_Android_CoBan.rar
Code:http://www.mediafire.com/file/1qle7ga7slawhbe/communityuni.com%23%23%23SourceCodeAndroid_coban.rar
👉10) Android nâng cao:
Slide:http://www.mediafire.com/file/bbbd0b627gu1rn1/communityuni.com%23%23%23Slides_Android_NangCao.rar
Code:http://www.mediafire.com/file/612jtc3za39cddd/communityuni.com%23%23%23SourceCodeAndroid_NangCao.rar
Bài tập bổ sung: http://www.mediafire.com/file/5l4tlj9on5ft8a4/communityuni.com%23%23%23Bai%20Tap%20Android%20Bo%20Sung.docx
👉11) Android 6 tuần:
Slide + code: http://www.mediafire.com/file/qedu5upmgbvmlzb/communityuni.com%23%23%23Android6tuan_code_slide.rar
👉12) Kotlin cơ bản:
Slide:http://www.mediafire.com/file/ibe8wewbvbslb2f/communityuni.com%23%23%23Slides_Kotlin_ToanTap.rar
Code: http://www.mediafire.com/file/tt7cuf487i363ge/communityuni.com%23%23%23SourceCode_Kotlin_ToanTap.rar
Giáo trình bổ sung: http://www.mediafire.com/file/qij4wa7xnba44m7/communityuni.com%23%23%23Tailieulaptrinh-Kotlin.docx
👉13) Python Cơ bản:
Slide:http://www.mediafire.com/file/qjiitst3iwr9nil/communityuni.com%23%23%23Slides_Python.rar/file
Code:http://www.mediafire.com/file/css8f6c82bx1o42/communityuni.com%23%23%23Practice.rar/file
👉14) Webservice cho di động:
Slide:http://www.mediafire.com/file/bxe1dwq0e7d79fm/communityuni.com%23%23%23Slides_Webservice.rar
Code + CSDL: http://www.mediafire.com/file/5bi56q31i4dacae/communityuni.com%23%23%23SourceCode_Webservice.rar
👉15) Webservice Web API RESTful:
Slide:http://www.mediafire.com/file/hzo66tnqsdi6r5n/communityuni.com%23%23%23Slides_Restful.rar
Code: http://www.mediafire.com/file/3adsj8013sksjyt/communityuni.com%23%23%23SourceCode_restful.rar
Các khóa học khi có sẽ được cập nhật trên http://communityuni.com/
https://duythanhcse.wordpress.com/
Thầy Thanh

 

Các Em like và follow page https://www.facebook.com/communityuni/ để hỏi các câu hỏi lập trình trong này cũng như theo dõi các thông báo.
Cài sẵn Ultraview, để bài nào không hiểu mà sửa lỗi mãi không được thì Remote Thầy hướng dẫn.

Thầy Thanh

C#-Xuất dữ liệu SQL Server ra Excel để báo cáo


Trong quá trình thực hiện phần mềm, vấn đề xuất báo cáo: ra file cứng (giấy, tức là từ phần mềm xuất thẳng dữ liệu ra giấy trong máy in luôn), file mềm (Excel, PDF, Word, HTML, Image…) thì Tui thấy nhu cầu xuất ra file Excel cũng khá phổ biến. Vì vậy Tui làm một số Tips hữu ích không có sắp xếp thứ tự như các bài học giảng giải về 1 công nghệ. Mỗi bài sẽ là 1 Tip hoàn chỉnh.

Cụ Thể trong bài này: Ta có dữ liệu từ SQL Server –> xuất ra Excel để báo cáo:

Hình trên Tui chụp 1 CSDL mẫu tên là “CSDL_MAU”, nó chỉ có 1 bảng duy nhất là “SanPham”, trong bảng này có 4 cột (MaSP, TenSp, DonGiaNhap, DonGiaXuat). Sau đó nhiệm vụ của ta là xuất dữ liệu từ bảng đó ra file Excel gọi lfa file Thống Kê Sản Phẩm. Lưu ý File Excel này khi xuất ta phải định dạng y xì boong vậy luôn nha, có Merge dòng/cột. có màu nền màu chữ, có kẻ khung.

Để làm được bài này thì trước tiên ta phải biết cách kết nối Cơ sở dữ liệu (ta có thể học 2 Khóa độc lập C# nâng cao hoặc LINQ). Trong tip này Tui dùng LINQ.

Đồng thời để kết xuất ra File Excel, ta có rất nhiều thư viện. Tuy nhiên trong Tip này Tui sử dụng thư viện có sẵn của Microsoft khi ta cài đặt công cụ Office, đó là thư viện: Microsoft.Office.CoreMicrosoft.Office.Interop.Excel

Ta tiến hành làm nha:

Bước 1: Phải có dữ liệu trước thì mới làm ra cơm phở.

Vụ CSDL các em tự xử nha, dùng version nào cũng được. Tui dùng SQL Server 2017. Để tiết kiệm thời gian cho các Em, Tui để Script của CSDL này, các Em chỉ cần Run Script 1 cái vèo cho lẹ:

Script bấm vào đây mà tải (CSDL_MAU)

Bước 2:

Tạo 1 project C# tên là “TestReportExcel” (dùng Winform hay WPF cũng được, không quan trọng). Ở đây Tui dùng Winform:

Chọn như trên đó, rùi bấm OK:

Bước 3: Kết nối CSDL bằng LINQ

Bấm chuột phải vào Project chọn Add/ New Item:

Chọn LINQ to SQL Classes, mục Name đặt CSDL_MAU.dbml (Lưu ý nếu không thấy LINQ tức là chưa biết cài Visual Studio nha)

Sau đó bấm nút Add:

Tập tin CSDL_MAU.dbml sẽ xuất hiện như trên. Ta bấm vào mục Server Explorer để kết nối CSDL:

Bấm vào nút Connect to Database:

Chọn Microsoft SQL Server rồi bấm OK:

Server Name (1): Chọn Tên Server của bạn lúc cài đặt SQL Server

Authentication (2): Chọn Windows hoặc SQL Mode. Chọn loại nào cũng được. miễn sao kết nối được

Database Name (3): Chọn Tên CSDL mà ta đã tạo CSDL_MAU

OK(4) : bấm OK để truy suất

Ta thấy CSDL_MAU xuất hiện trong Server Explorer. Bấm vào bảng SanPham Túm kéo nó vào phần mềm như hướng dẫn ở trên, ta có kết quả:

Như vậy là đã kết nối xong

Bước 4: Hiển thị dữ liệu lên Giao diện, cụ thể là GridView

Ta kéo thả 2 Button và 1 DataGridView như trên. Coding cho nút tải dữ liệu như sau:


private void btnTaiDuLieu_Click(object sender, EventArgs e)
{
CSDL_MAUDataContext context = new CSDL_MAUDataContext();
gvSanPham.DataSource = context.SanPhams.ToList();
}

Vô cùng đơn giản, chỉ cần 2 dòng lên trên thôi ta đã có dữ liệu hiển thị lên Giao diện.

Bước 5: Xuất dữ liệu ra File Excel để báo cáo (Theo đúng định dạng yêu cầu)

Ta tham chiếu thư viện như sau:

Bấm chuột phải vào References/ chọn add Reference…

Ta chọn COM, rồi tick vào 2 thư viện như trên: Microsoft Office 16.0 Object Library,  Microsoft Excel 16.0 Object Library (Dĩ nhiên do Tui dùng Office 2016 nên có cái này, còn bạn sài 2010, 2013… thì nó phải khác nha, thấy số 14, 15 thì chọn. tên na ná như vậy).

BẤM OK, thấy được thư viện tham chiếu như bên dưới là Ngon lành cành đào:

Bây giờ Coding Xuất Excel nha (Lưu ý là khi dữ liệu lớn thì bắt buộc phải viết dạng đa tiến trình, cụ thể là dùng BackgroundWorker để export Step by Step giúp chạy realtime mà không bị Treo phần mềm). Tuy nhiên để đơn giản thì Tui lược bỏ phần đa tiến trình này đi, bạn muốn dùng thì xem Khóa C# nâng cao có hướng dẫn phần Background Worker, hoặc ở một bài khác Tui sẽ ví dụ cách dùng Đa tiến trình để chạy xuất file báo cáo.

Quay lại yêu cầu của bài toán, là sau khi chạy thì kết quả xuất Báo cáo File Excel phải y xì như bên dưới:

Quan sát : Dòng đầu tiền (dòng có số thứ tự là 1. Cột chạy từ A->E : Và Trộn các cột này lại với nhau thành dòng tiêu đề “Thống kê sản phẩm“.

Bên dưới dòng 2 và 3 là Tên Trường (tên cột) để hiển thị thông tin chi tiết. Thì lưu ý  Cột A, B, C là trộn 2 dòng. Còn cột D, E thì dòng bên trên là trộn 2 cột để ra chữ “Giá sản phẩm”, và ngay bên dưới có 2 cột là “Giá bán” và “Giá Xuất”.

==> Đây chính là chỗ khó nhất để xuất file báo cáo này.

Còn tất cả dữ liệu bên dưới ta dùng vòng lặp xuất ra là xong.

sau khi xuất dữ liệu xong thì phải Kẻ bảng cũng như tô màu nền màu chữ nếu có.

Chi tiết Coding cho phần xuất Excel như sau:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
using Microsoft.Office.Interop.Excel;

namespace TestReportExcel
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void btnTaiDuLieu_Click(object sender, EventArgs e)
{
CSDL_MAUDataContext context = new CSDL_MAUDataContext();
gvSanPham.DataSource = context.SanPhams.ToList();
}

private void btnXuatExcel_Click(object sender, EventArgs e)
{
try
{
string saveExcelFile = @"f:\excel_report.xlsx";

Excel.Application xlApp = new Excel.Application();

if (xlApp == null)
{
MessageBox.Show("Lỗi không thể sử dụng được thư viện EXCEL");
return;
}
xlApp.Visible = false;

object misValue = System.Reflection.Missing.Value;

Workbook wb = xlApp.Workbooks.Add(misValue);

Worksheet ws = (Worksheet)wb.Worksheets[1];

if (ws == null)
{
MessageBox.Show("Không thể tạo được WorkSheet");
return;
}
int row = 1;
string fontName = "Times New Roman";
int fontSizeTieuDe = 18;
int fontSizeTenTruong = 14;
int fontSizeNoiDung = 12;
//Xuất dòng Tiêu đề của File báo cáo: Lưu ý
Range row1_TieuDe_ThongKeSanPham = ws.get_Range("A1", "E1");
row1_TieuDe_ThongKeSanPham.Merge();
row1_TieuDe_ThongKeSanPham.Font.Size = fontSizeTieuDe;
row1_TieuDe_ThongKeSanPham.Font.Name = fontName;
row1_TieuDe_ThongKeSanPham.Cells.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
row1_TieuDe_ThongKeSanPham.Value2 = "Thống kê sản phẩm";

//Tạo Ô Số Thứ Tự (STT)
Range row23_STT = ws.get_Range("A2", "A3");//Cột A dòng 2 và dòng 3
row23_STT.Merge();
row23_STT.Font.Size = fontSizeTenTruong;
row23_STT.Font.Name = fontName;
row23_STT.Cells.HorizontalAlignment = XlHAlign.xlHAlignCenter;
row23_STT.Value2 = "STT";

//Tạo Ô Mã Sản phẩm :
Range row23_MaSP = ws.get_Range("B2", "B3");//Cột B dòng 2 và dòng 3
row23_MaSP.Merge();
row23_MaSP.Font.Size = fontSizeTenTruong;
row23_MaSP.Font.Name = fontName;
row23_MaSP.Cells.HorizontalAlignment = XlHAlign.xlHAlignCenter;
row23_MaSP.Value2 = "Mã Sản Phẩm";
row23_MaSP.ColumnWidth = 20;

//Tạo Ô Tên Sản phẩm :
Range row23_TenSP = ws.get_Range("C2", "C3");//Cột C dòng 2 và dòng 3
row23_TenSP.Merge();
row23_TenSP.Font.Size = fontSizeTenTruong;
row23_TenSP.Font.Name = fontName;
row23_TenSP.Cells.HorizontalAlignment = XlHAlign.xlHAlignCenter;
row23_TenSP.ColumnWidth = 20;
row23_TenSP.Value2 = "Tên Sản Phẩm";

//Tạo Ô Giá Sản phẩm :
Range row2_GiaSP = ws.get_Range("D2", "E2");//Cột D->E của dòng 2
row2_GiaSP.Merge();
row2_GiaSP.Font.Size = fontSizeTenTruong;
row2_GiaSP.Font.Name = fontName;
row2_GiaSP.Cells.HorizontalAlignment = XlHAlign.xlHAlignCenter;
row2_GiaSP.Value2 = "Giá Sản Phẩm";

//Tạo Ô Giá Nhập:
Range row3_GiaNhap = ws.get_Range("D3", "D3");//Ô D3
row3_GiaNhap.Font.Size = fontSizeTenTruong;
row3_GiaNhap.Font.Name = fontName;
row3_GiaNhap.Cells.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
row3_GiaNhap.Value2 = "Giá Nhập";
row3_GiaNhap.ColumnWidth = 20;

//Tạo Ô Giá Xuất:
Range row3_GiaXuat = ws.get_Range("E3", "E3");//Ô E3
row3_GiaXuat.Font.Size = fontSizeTenTruong;
row3_GiaXuat.Font.Name = fontName;
row3_GiaXuat.Cells.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
row3_GiaXuat.Value2 = "Giá Xuất";
row3_GiaXuat.ColumnWidth = 20;
//Tô nền vàng các cột tiêu đề:
Range row23_CotTieuDe = ws.get_Range("A2", "E3");
//nền vàng
row23_CotTieuDe.Interior.Color = ColorTranslator.ToOle(System.Drawing.Color.Yellow);
//in đậm
row23_CotTieuDe.Font.Bold = true;
//chữ đen
row23_CotTieuDe.Font.Color = ColorTranslator.ToOle(System.Drawing.Color.Black);

int stt = 0;
row = 3;//dữ liệu xuất bắt đầu từ dòng số 4 trong file Excel (khai báo 3 để vào vòng lặp nó ++ thành 4)
CSDL_MAUDataContext context = new CSDL_MAUDataContext();
foreach (SanPham sp in context.SanPhams)
{
stt++;
row++;
dynamic []arr = { stt,sp.MaSP,sp.TenSP,sp.DonGiaNhap,sp.DonGiaXuat};
Range rowData = ws.get_Range("A"+row, "E"+row);//Lấy dòng thứ row ra để đổ dữ liệu
rowData.Font.Size = fontSizeNoiDung;
rowData.Font.Name = fontName;
rowData.Value2 = arr;
}
//Kẻ khung toàn bộ
BorderAround(ws.get_Range("A2", "E" + row));

//Lưu file excel xuống Ổ cứng
wb.SaveAs(saveExcelFile);

//đóng file để hoàn tất quá trình lưu trữ
wb.Close(true, misValue, misValue);
//thoát và thu hồi bộ nhớ cho COM
xlApp.Quit();
releaseObject(ws);
releaseObject(wb);
releaseObject(xlApp);

//Mở File excel sau khi Xuất thành công
System.Diagnostics.Process.Start(saveExcelFile);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//Hàm kẻ khung cho Excel
private void BorderAround(Range range)
{
Borders borders = range.Borders;
borders[XlBordersIndex.xlEdgeLeft].LineStyle = XlLineStyle.xlContinuous;
borders[XlBordersIndex.xlEdgeTop].LineStyle = XlLineStyle.xlContinuous;
borders[XlBordersIndex.xlEdgeBottom].LineStyle = XlLineStyle.xlContinuous;
borders[XlBordersIndex.xlEdgeRight].LineStyle = XlLineStyle.xlContinuous;
borders.Color = Color.Black;
borders[XlBordersIndex.xlInsideVertical].LineStyle = XlLineStyle.xlContinuous;
borders[XlBordersIndex.xlInsideHorizontal].LineStyle = XlLineStyle.xlContinuous;
borders[XlBordersIndex.xlDiagonalUp].LineStyle = XlLineStyle.xlLineStyleNone;
borders[XlBordersIndex.xlDiagonalDown].LineStyle = XlLineStyle.xlLineStyleNone;
}
//Hàm thu hồi bộ nhớ cho COM Excel
private static void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
obj = null;
}
finally
{ GC.Collect(); }
}
}
}

Chạy lên ta sẽ có kết quả như mong muốn.

Đây là source code đầy đủ: Tải code

Ngoài ra Tui có tạo 1 Facebook Fanpage để hướng dẫn cũng như trả lời các thắc mắc của Sinh viên về các kiến thức lập trình mà Tui đang đảm nhiệm, các bạn có thể Like + Follow để dễ dàng theo dõi các Tip cũng như có thể tham gia thảo luận: https://www.facebook.com/communityuni

Chúc các bạn thành công!

Bài 35-Truy cập NodeJS RESTful Web Services với thư viện Volley và Retrofit (FINAL)


Đây là bài học cuối cùng, kết thúc chuỗi series bài học về NodeJS- MongoDB. Toàn bộ bài học được tổng hợp trong trang này.

Có rất nhiều kỹ thuật để truy cập các WEB API, tùy vào nhu cầu của lập trình viên mà ta lựa chọn các thư viện khác nhau. Ở đây dân chúng hay bàn luận về Volley Retrofit cũng như so sánh phân vân nên chọn cái nào? mấy câu hỏi này bạn tự Google search nha. Bạn chỉ cần biết là ta có thêm 2 thư viện Volley Retrofit để truy cập WEB API là đủ rồi, còn cụ thể như thế nào thì cứ hỏi bác Google là OK á.

Trong bài này Tui chỉ giới thiệu sơ Volley để lấy danh sách Product thôi nha (chi tiết bạn xem trên Blog của Alif’s Blog để áp dụng cho các Web API còn lại, nó vô cùng đơn giản nhưng Tui busy quá không quá trình bày tất tần tật được), Retrofit bạn tự search.

Bước 1:

Tạo một Android Kotlin Project tên VolleyToNodeJS.

thêm lệnh api ‘com.android.volley:volley:1.1.0’ trong build.gradle của app level

Sau khi gõ lệnh xong thì nhớ bấm mục số 2 (Sync now)==>Lúc này thư viện volley sẽ được đưa vào ứng dụng và ta sử dụng nó một cách dễ dàng, đơn giản nhất.

Bước 2:

Thêm một ListView cho màn hình chính MainActivity như sau:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">

<ListView
android:id="@+id/lvProduct"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

Bước 3:

Coding sử dụng Volley để triệu gọi Web API lấy danh sách Product đơn giản như sau:


fun TaiDanhSachProduct_Volley()
{
var url="http://192.168.1.137/nodejsapi/products"
val queue = Volley.newRequestQueue(this)

val getRequest = JsonArrayRequest(Request.Method.GET, url, null,
object : Response.Listener<JSONArray> {
override fun onResponse(response: JSONArray) {
//response là 1 JSonArray chưa danh sách Product->ta phân tích để lấy dữ liệu trong này ra là ok
}
},
object : Response.ErrorListener {
override fun onErrorResponse(error: VolleyError) {
Log.d("Error.Response", error.toString())
}
}
)
queue.add(getRequest)
}

Tổng thể ta có coding cuối cùng cho MainActivity như sau:


package com.communityuni.volleytonodejs

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.ArrayAdapter
import android.widget.ListView
import com.android.volley.Request
import com.android.volley.toolbox.Volley
import com.android.volley.RequestQueue
import com.android.volley.Response
import com.android.volley.VolleyError
import com.android.volley.toolbox.JsonArrayRequest
import org.json.JSONObject
import com.android.volley.toolbox.JsonObjectRequest
import org.json.JSONArray

class MainActivity : AppCompatActivity() {

lateinit var lvProduct:ListView
lateinit var adapter: ArrayAdapter<String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
addControls()
}
private fun addControls() {
lvProduct=findViewById(R.id.lvProduct)
adapter= ArrayAdapter(this,android.R.layout.simple_list_item_1)
lvProduct.adapter=adapter
}

override fun onResume() {
super.onResume()
TaiDanhSachProduct_Volley()
}
fun TaiDanhSachProduct_Volley()
{
var url="http://192.168.1.137/nodejsapi/products"
val queue = Volley.newRequestQueue(this)

val getRequest = JsonArrayRequest(Request.Method.GET, url, null,
object : Response.Listener<JSONArray> {
override fun onResponse(response: JSONArray) {
//response là 1 JSonArray chưa danh sách Product
adapter.clear()
for (i in 0 until response.length())
{
var jsonObject=response.getJSONObject(i)
var line=jsonObject.getString("Ma")+
"\n"+jsonObject.getString("Ten")+
"\n"+jsonObject.getDouble("DonGia")
adapter.add(line)
}
}
},
object : Response.ErrorListener {
override fun onErrorResponse(error: VolleyError) {
Log.d("Error.Response", error.toString())
}
}
)
queue.add(getRequest)
}
}

Chạy lên ta có kết quả:

Còn các API khác (POST, PUT, DELETE, GET chi tiết Product) các bạn cố gắng tự mày mò nha.Vì Volley là một trong những thư viện vô cùng đơn giản, dễ sử dụng và rất hiệu quả, nếu không làm được thì có thể add Facebook http://facebook.com/duythanhcse , Tui sẽ support khi rảnh

Coding của bài này tải ở đây

Chúc các bạn thành công!

Bài 34-Truy cập NodeJS RESTful Web Services bằng Android Kotlin-HTTPPOST


Chúc mừng các bạn đã lết được tới Web API cuối cùng, đó là triệu gọi HTTPPOST để thêm mới Product. Tiếp tục mở lại project AndroidKotlinToNodeJS bài 33.

Trong bài này các bạn bổ sung 1 Menu “Thêm Product”, nhấn vào menu này sẽ hiển thị ra màn hình Thêm mới để cho phép người dùng nhập mới Product, bấm lưu để thêm Product vào MongoDB bằng cách triệu gọi Web API http://192.168.1.137/nodejsapi/addProduct (dĩ nhiên máy bạn cấu hình sao thì lấy theo vậy, copy y xì Tui là đạp xích lô đó nha).

Chi tiết các bước coding như sau:

Bước 1: Tạo 1 Option Menu cho ứng dụng, Option menu này chứa 1 MenuItem là Thêm Product

Bấm chuộc phải vào thư mục res/ chọn New/ chọn Directory:

Đặt tên là menu rồi bấm OK

Khi thư mục menu được tạo ra, ta bấm chuột phải vào nó/ chọn New/ chọn Menu Resource file:

Đặt tên main_menu rồi bấm OK

Ta kéo một Menu Item vào trong menu, đặt id là mnuThemProduct, nhãn là “Thêm Product”

cấu trúc XML của main_menu.xml như sau:


<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@+id/mnuThemProduct" android:title="Thêm Product" />
</menu>


Nạp Menu này vào cho màn hình chính (MainActivity) bằng cách override 2 hàm sau:


override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.main_menu,menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
if(item!!.itemId==R.id.mnuThemProduct)
{
var intent=Intent(this,ThemProductActivity::class.java)
startActivity(intent)
}
return super.onOptionsItemSelected(item)
}

Chú ý ở trên Tui có xử lý sự kiện khi người dùng nhấn vào menu Thêm Product thì mở màn hình ThemProductActivity (xem bước 2)
Bước 2: Tạo một màn hình mới tên là ThemProductActivity

Tương tự như tạo màn hình ChiTietActivity, ta cũng Bấm chuột phải vào Package chứa MainActivity rồi chọn New/ chọn Activity/ chọn Empty Activity

đặt tên ThemProductActivity và cấu hình như trên rồi bấm Finish

tiến hành thiết kế giao diện cho màn hình Thêm Product (chỉnh layout cho activity_them_product.xml), màn hình này phải cung cấp ô nhập: Mã, Tên, Đơn giá:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".ThemProductActivity">
<TextView android:id="@+id/textView2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Mã Product:" android:textSize="20sp" />

<EditText android:id="@+id/edtMa" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="textPersonName" />

<TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Tên Product:" android:textSize="20sp" />

<EditText android:id="@+id/edtTen" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="textPersonName" />
<TextView android:id="@+id/textView3" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Đơn giá:" android:textSize="20sp" />

<EditText android:id="@+id/edtDonGia" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="numberDecimal" />

<Button android:onClick="xuLyThemMoiProduct" android:id="@+id/btnLuu" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Đổi thông tin" android:textSize="20sp" />

</LinearLayout>

Giao diện bên GUI sẽ như sau:

Bước 3: Coding cho ThemProductActivity

Coding khởi tạo các biến control để truy suất tới các ô nhập liệu như Mã, Tên, đơn giá:


package com.communityuni.androidkotlintonodejs

import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.EditText
import android.widget.Toast
import com.communityuni.model.Product
import java.io.BufferedWriter
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.net.URL

class ThemProductActivity : AppCompatActivity() {
lateinit var edtMa: EditText
lateinit var edtTen: EditText
lateinit var edtDonGia: EditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_them_product)
addControls()
}
private fun addControls() {
edtMa=findViewById(R.id.edtMa)
edtTen=findViewById(R.id.edtTen)
edtDonGia=findViewById(R.id.edtDonGia)
}
fun xuLyThemMoiProduct(v:View)
{

}
private fun thongBao(result: Boolean?) {
if(result==true)
{
Toast.makeText(applicationContext,"Thêm mới Product thành công", Toast.LENGTH_LONG).show()
finish()
}
else
{
Toast.makeText(applicationContext,"Thêm mới Product thất bại", Toast.LENGTH_LONG).show()
}
}
}

Tiếp tục bổ sung thêm đa tiến trình HTTPPOSTProductTask trong màn hình ThemProductActivity để triệu gọi API thêm mới Product (http://192.168.1.137/nodejsapi/addProduct)


inner class HTTPPOSTProductTask : AsyncTask<Product, Void, Boolean>()
{
override fun doInBackground(vararg p0: Product?): Boolean {
var p:Product?=p0[0]
try
{
var api="http://192.168.1.137/nodejsapi/addProduct"
var url=URL(api)
var urlConnection= url.openConnection() as HttpURLConnection
urlConnection.requestMethod="POST"
urlConnection.doOutput=true
urlConnection.doInput=true
urlConnection.addRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
val outputStream = urlConnection.getOutputStream()
val bufferedWriter = BufferedWriter(OutputStreamWriter(outputStream, "UTF-8"))
val put_data = p!!.parameters()
bufferedWriter.write(put_data)
bufferedWriter.flush()
bufferedWriter.close()
outputStream.close()
var result =urlConnection.inputStream.bufferedReader().readText()
urlConnection.disconnect()
return result.equals("true")
}
catch (ex:Exception)
{
Log.e("LOI",ex.toString())
}
return false
}
override fun onPostExecute(result: Boolean?) {
super.onPostExecute(result)
thongBao(result)
}
}

Bổ sung thêm coding cho sự kiện xuLyThemMoiProduct:


fun xuLyThemMoiProduct(v:View)
{
var Ma=edtMa.text.toString()
var Ten=edtTen.text.toString()
var DonGia=edtDonGia.text.toString().toDouble()
var p=Product(Ma,Ten,DonGia)
HTTPPOSTProductTask().execute(p)
}

Cuối cùng cho có Coding toàn bộ của màn hình ThemProductActivity như sau:


package com.communityuni.androidkotlintonodejs

import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.EditText
import android.widget.Toast
import com.communityuni.model.Product
import java.io.BufferedWriter
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.net.URL

class ThemProductActivity : AppCompatActivity() {
lateinit var edtMa: EditText
lateinit var edtTen: EditText
lateinit var edtDonGia: EditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_them_product)
addControls()
}
private fun addControls() {
edtMa=findViewById(R.id.edtMa)
edtTen=findViewById(R.id.edtTen)
edtDonGia=findViewById(R.id.edtDonGia)
}
fun xuLyThemMoiProduct(v:View)
{
var Ma=edtMa.text.toString()
var Ten=edtTen.text.toString()
var DonGia=edtDonGia.text.toString().toDouble()
var p=Product(Ma,Ten,DonGia)
HTTPPOSTProductTask().execute(p)
}
private fun thongBao(result: Boolean?) {
if(result==true)
{
Toast.makeText(applicationContext,"Thêm mới Product thành công", Toast.LENGTH_LONG).show()
finish()
}
else
{
Toast.makeText(applicationContext,"Thêm mới Product thất bại", Toast.LENGTH_LONG).show()
}
}
inner class HTTPPOSTProductTask : AsyncTask<Product, Void, Boolean>()
{
override fun doInBackground(vararg p0: Product?): Boolean {
var p:Product?=p0[0]
try
{
var api="http://192.168.1.137/nodejsapi/addProduct"
var url=URL(api)
var urlConnection= url.openConnection() as HttpURLConnection
urlConnection.requestMethod="POST"
urlConnection.doOutput=true
urlConnection.doInput=true
urlConnection.addRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
val outputStream = urlConnection.getOutputStream()
val bufferedWriter = BufferedWriter(OutputStreamWriter(outputStream, "UTF-8"))
val put_data = p!!.parameters()
bufferedWriter.write(put_data)
bufferedWriter.flush()
bufferedWriter.close()
outputStream.close()
var result =urlConnection.inputStream.bufferedReader().readText()
urlConnection.disconnect()
return result.equals("true")
}
catch (ex:Exception)
{
Log.e("LOI",ex.toString())
}
return false
}
override fun onPostExecute(result: Boolean?) {
super.onPostExecute(result)
thongBao(result)
}
}
}

Chạy phần mềm lên ta sẽ có được kết quả như mong muốn : Mở được màn hình thêm mới Product, triệu gọi API thêm mới thành công. Như vậy ta đã hoàn thành xong bài triệu gọi Web API HTTPPOST để thêm mới 1 Product.

Source code Triệu gọi Web API thêm mới Product tải ở đây.

Bài sau Tui sẽ giới thiệu cho các Thím một số thư viện Third Party để truy suất RESTful Webservice, như Volley, Retrofit… các Thím tranh thủ theo dõi để đọc nhé

Các khóa học online khác, bạn có thể tham khảo tại đây: http://communityuni.com/

Innovate Trading System (Kênh đầu tư lợi nhuận rất cao), các bạn nào quan tâm thì vào đây đầu tư nhé:

Chúc các bạn thành công!

Bài 33-Truy cập NodeJS RESTful Web Services bằng Android Kotlin-HTTPDELETE


Như vậy các bạn đã triệu gọi thành công được 3 RESTful Web API trong ví dụ (lấy danh sách Product, xem chi tiết Product và chỉnh sửa thông tin Product). Bài này ta sẽ coding để Xóa Product khỏi MongoDB thông qua việc triệu gọi API HTTPDELETE.

Cụ thể, trong màn hình đầu tiên hiển thị danh sách Product, ta nhấn vào biểu tượng sọt rác, Chương trình sẽ hiển thị cửa sổ hỏi có muốn Xóa hay không (AlertDialog). Nếu chọn Không thì trở về màn hình ban đâu, nếu chọn Có Chứ thì sẽ Xóa Product đó đồng thời gọi lại API hiển thị Danh sách Product để tại lại và hiển thị lên Listview với danh sách mới sau khi xóa.

Vậy ta coding như sau:

Bước 1:

Trong lớp ProductAdapter, bổ sung thêm inner class để xử lý đa tiến trình tên là HTTPDELETEProductTask triệu gọi API xóa Product, coding:


inner class HTTPDELETEProductTask : AsyncTask<Product, Void, Boolean>()
{
override fun doInBackground(vararg p0: Product?): Boolean {
var p:Product?=p0[0]
try
{
var api="http://192.168.1.137/nodejsapi/deleteProduct"
var url= URL(api)
var urlConnection= url.openConnection() as HttpURLConnection
urlConnection.requestMethod="DELETE"
urlConnection.doOutput=true
urlConnection.doInput=true
urlConnection.addRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
val outputStream = urlConnection.getOutputStream()
val bufferedWriter = BufferedWriter(OutputStreamWriter(outputStream, "UTF-8"))
val put_data = "Ma="+p!!.Ma
bufferedWriter.write(put_data)
bufferedWriter.flush()
bufferedWriter.close()
outputStream.close()
var result =urlConnection.inputStream.bufferedReader().readText()
urlConnection.disconnect()
return result.equals("true")
}
catch (ex:Exception)
{
Log.e("LOI",ex.toString())
}
return false
}
override fun onPostExecute(result: Boolean?) {
super.onPostExecute(result)
if(result==true)
{
(context as MainActivity).HTTPGetListProductTask().execute()
}
}
}

Đầu vào là 1 Product (Product này được lấy ra khi ta nhấn vào nút Xóa)

Vì muốn Xóa thì chỉ cần gửi Ma lên mà thôi, nên trong coding Tui viết luôn: val put_data = “Ma=”+p!!.Ma

Bước 2:

Trong hàm getView của ProductAdapter, ta bổ sung khai báo biến và gán sự kiện cho nút Xóa như sau:


var imgDelete=custom.findViewById<ImageView>(R.id.imgDelete)
imgDelete.setOnClickListener{xuLyDelete(p)}

hàm xuLyDelete được viết như sau:


private fun xuLyDelete(p: Product?) {
var builder=AlertDialog.Builder(context)
builder.setTitle("Xác nhận xóa")
builder.setMessage("Thím có chắc chắn muốn xóa Product ["+p!!.Ten+"] không?")
builder.setNegativeButton("Không",
DialogInterface.OnClickListener
{ dialogInterface, i -> dialogInterface.dismiss()})
builder.setPositiveButton("Có chứ", DialogInterface.OnClickListener
{ dialogInterface, i ->
HTTPDELETEProductTask().execute(p)
})
builder.create().show()
}

Vậy cuối cùng ta có coding đầy đủ của lớp ProductAdapter như dưới đây:

package com.communityuni.adapter

import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.os.AsyncTask
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import com.communityuni.androidkotlintonodejs.ChiTietActivity
import com.communityuni.androidkotlintonodejs.MainActivity
import com.communityuni.androidkotlintonodejs.R
import com.communityuni.model.Product
import java.io.BufferedWriter
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.net.URL

class ProductAdapter(internal var context: Activity, internal var resource: Int) : ArrayAdapter<Product>(context, resource) {

override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
var custom = context.layoutInflater.inflate(resource, null)
var txtMa = custom.findViewById<TextView>(R.id.txtMa)
var txtTen = custom.findViewById<TextView>(R.id.txtTen)
var txtDonGia = custom.findViewById<TextView>(R.id.txtDonGia)
var p = getItem(position)
txtMa.text = p!!.Ma
txtTen.text = p.Ten
txtDonGia.text = p.DonGia.toString()
var img=custom.findViewById<ImageView>(R.id.imgEdit)
img.setOnClickListener { xuLyEdit(p) }
var imgDelete=custom.findViewById<ImageView>(R.id.imgDelete)
imgDelete.setOnClickListener{xuLyDelete(p)}
return custom
}
private fun xuLyEdit(p: Product?) {
var i=Intent(context,ChiTietActivity::class.java)
i.putExtra("Ma",p!!.Ma)
context.startActivity(i)
}
private fun xuLyDelete(p: Product?) {
var builder=AlertDialog.Builder(context)
builder.setTitle("Xác nhận xóa")
builder.setMessage("Thím có chắc chắn muốn xóa Product ["+p!!.Ten+"] không?")
builder.setNegativeButton("Không",
DialogInterface.OnClickListener
{ dialogInterface, i -> dialogInterface.dismiss()})
builder.setPositiveButton("Có chứ", DialogInterface.OnClickListener
{ dialogInterface, i ->
HTTPDELETEProductTask().execute(p)
})
builder.create().show()
}
inner class HTTPDELETEProductTask : AsyncTask<Product, Void, Boolean>()
{
override fun doInBackground(vararg p0: Product?): Boolean {
var p:Product?=p0[0]
try
{
var api="http://192.168.1.137/nodejsapi/deleteProduct"
var url= URL(api)
var urlConnection= url.openConnection() as HttpURLConnection
urlConnection.requestMethod="DELETE"
urlConnection.doOutput=true
urlConnection.doInput=true
urlConnection.addRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
val outputStream = urlConnection.getOutputStream()
val bufferedWriter = BufferedWriter(OutputStreamWriter(outputStream, "UTF-8"))
val put_data = "Ma="+p!!.Ma
bufferedWriter.write(put_data)
bufferedWriter.flush()
bufferedWriter.close()
outputStream.close()
var result =urlConnection.inputStream.bufferedReader().readText()
urlConnection.disconnect()
return result.equals("true")
}
catch (ex:Exception)
{
Log.e("LOI",ex.toString())
}
return false
}
override fun onPostExecute(result: Boolean?) {
super.onPostExecute(result)
if(result==true)
{
(context as MainActivity).HTTPGetListProductTask().execute()
}
}
}
}

Chạy phần mềm lên và thao tác Xóa sẽ thành công như Tui hướng dẫn nha.

Như vậy ta đã hoàn thành xong bài triệu gọi Web API HttpDelete để xóa 1 Product.

Source code Triệu gọi Web API xóa Product tải ở đây.

Bài sau Tui sẽ hướng dẫn các Thím cách dùng Android Kotlin để  truy cập API RESTful Thêm mới Product như thế nào. Các bạn chú ý theo dõi nhé (vẫn dùng lại Project này)

Các khóa học online khác, bạn có thể tham khảo tại đây: http://communityuni.com/

Innovate Trading System (Kênh đầu tư lợi nhuận rất cao), các bạn nào quan tâm thì vào đây đầu tư nhé:

Chúc các bạn thành công!

Bài 32-Truy cập NodeJS RESTful Web Services bằng Android Kotlin-HTTPPUT


Tiếp tục mở lại Project AndroidKotlinToNodeJS trong bài 31. Bài học này Tui sẽ hướng dẫn các bạn cách triệu gọi API với HTTPPUT Method (để chỉnh sửa dữ liệu của một Product).

Lưu ý là IISNode của toàn bộ API này được deploy trong bài 28. Và API Edit Product được trình bày chi tiết trong bài 26. Nếu nếu các Thím có quên thì coi lại những bài này (tốt nhất là đừng quên, cứ làm theo tuần tự từ bài 1->bài cuối cùng thì chắc chắn không bao giờ quên. Đừng tỏ vẻ nguy hiểm nhảy cóc sẽ mất thời gian, vì các bài học Tui đã chủ ý thiết kế từ cơ bản đến nâng cao mà bài sau kế thừa bài trước).

Nhắc lại ở bài 31 ta đã triệu gọi API HTTPGET để lấy chi tiết thông tin của một Product hiển thị lên 1 màn hình mới rồi, giờ cũng trong màn hình hiển thị chi tiết đó ta chỉnh sửa thông tin của TÊN + ĐƠN GIÁ rồi bấm lưu thay đổi–>triệu gọi API HTTPPUT để thay đổi.

Xem giao diện minh họa dưới đây:

Bước 1: Trong màn hình chính hiển thị danh sách Product, nhấn vào nút Edit

Bước 2: Thông tin chi tiết được hiển thị lên màn hình chi tiết

Bước 3: Trong màn hình chi tiết ta sửa tên và đơn giá rồi bấm nút “Đổi thông tin”

Bước 4: Chương trình tải lại và ta thấy kết quả thay đổi.

Chi tiết các bước lập trình để triệu gọi API HTTPUT chỉnh sửa thông tin Product như sau (trong bài học Tui hướng dẫn thì API này là: http://192.168.1.137/nodejsapi/editProduct (của bạn cấu hình thế nào thì lấy thế đó nha, copy y xì như của Tui là đi đạp xích lô đó nha).

Xem lại hình thử nghiệm trong bài 28:

Ở trên ta thấy cần phải truyền 3 Parameter (Ma, Ten, DonGia) từ Android lên cho NodeJS xử lý. Vậy truyền như thế nào? Lưu ý có nhiều thư viện như volley, retrofit… để hỗ trợ tương tác dịch vụ Web. Tuy nhiên các thư viện này Tui chưa sài, nếu có Tui sẽ hướng dẫn thêm ở những bài khác. Bây giờ hãy làm theo chuẩn HttpURLConnection trước.

OK, action nha.

Trong Project AndroidKotlinToNodeJS  các bạn làm theo bước sau:

Bước 1: Chỉnh sửa lớp Product.kt để tạo Parameter gửi lên Server NodeJS


package com.communityuni.model

import java.net.URLEncoder

class Product {
lateinit var _id:Any
lateinit var Ma:String
lateinit var Ten:String
var DonGia:Double=0.0
constructor(ma:String,ten:String,donGia:Double)
{
Ma=ma
Ten=ten
DonGia=donGia
}
override fun toString(): String {
return Ma+"\n"+Ten+"\n"+DonGia+"VNĐ"
}
public fun parameters(): String
{
return "Ma="+Ma+"&Ten="+URLEncoder.encode(Ten,"UTF-8")+"&DonGia="+DonGia
}
}

bạn thấy hàm parameters() ở trên không? Tui coding cho nó trả về 1 chuỗi có cú pháp, đây chính là các nội dung ta gửi lên Server NodeJS để xử lý. Những chuỗi nào liên quan Unicode thì ta phải dùng URLEncoder như trên để mã hóa nó nha, nếu quên sẽ bị failed. Các đối số cách nhau bởi dấu & nha, bạn thay dấu & bằng dấu khác cũng được nhưng mà sai.

Bước 2:

Xử lý coding nhấn vào nút Thay đổi thông tin.

Trong lớp ChiTietActivity.kt bổ sung thêm 1 inner class HTTPPUTProductTask nhiệm vụ của nó là triệu gọi API HTTPUT (http://192.168.1.137/nodejsapi/editProduct) và gửi dữ liệu lên NodeJS Server(dữ liệu được coding trong hàm parameter() của lớp Product.kt. (Bổ sung thêm coding tức là phải giữ nguyên coding cũ, coding cũ Tui không có đưa vào đây nha)


inner class HTTPPUTProductTask : AsyncTask<Product, Void, Boolean>()
{
override fun doInBackground(vararg p0: Product?): Boolean {
var p:Product?=p0[0]
try
{
var api="http://192.168.1.137/nodejsapi/editProduct"
var url=URL(api)
var urlConnection= url.openConnection() as HttpURLConnection
urlConnection.requestMethod="PUT"
urlConnection.doOutput=true
urlConnection.doInput=true
urlConnection.addRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
val outputStream = urlConnection.getOutputStream()
val bufferedWriter = BufferedWriter(OutputStreamWriter(outputStream, "UTF-8"))
val put_data = p!!.parameters()
bufferedWriter.write(put_data)
bufferedWriter.flush()
bufferedWriter.close()
outputStream.close()
var result =urlConnection.inputStream.bufferedReader().readText()
urlConnection.disconnect()
return result.equals("true")
}
catch (ex:Exception)
{
Log.e("LOI",ex.toString())
}
return false
}
override fun onPostExecute(result: Boolean?) {
super.onPostExecute(result)
thongBao(result)
}
}

Bước 3: Viết sự kiện cho nút Thay đổi thông tin để gọi đa tiến trình ở bước 2 (Sự kiện các bạn dùng onclick XML nha, nên Tui không chụp lại XML layout nữa vì nó chỉ có 1 thay  đổi nhỏ):


fun xuLyCapNhat(v:View)
{
var Ma=edtMa.text.toString()
var Ten=edtTen.text.toString()
var DonGia=edtDonGia.text.toString().toDouble()
var p=Product(Ma,Ten,DonGia)
HTTPPUTProductTask().execute(p)
}
private fun thongBao(result: Boolean?) {
if(result==true)
{
Toast.makeText(applicationContext,"Cập nhật thành công",Toast.LENGTH_LONG).show()
finish()
}
else
{
Toast.makeText(applicationContext,"Cập nhật thất bại",Toast.LENGTH_LONG).show()
}
}

OK, vậy là ngon lành cành đạo như cơm mẹ nấu rồi đó, chạy lên ta sẽ có kết quả như mong muốn

Như vậy ta đã hoàn thành xong bài triệu gọi Web API HttpPUT để chỉnh sửa thông tin của 1 Product.

Source code Triệu gọi Web API thay đổi thông tin Product tải ở đây.

Bài sau Tui sẽ hướng dẫn các Thím cách dùng Android Kotlin để  truy cập API RESTful Xóa Product như thế nào. Các bạn chú ý theo dõi nhé (vẫn dùng lại Project này)

Các khóa học online khác, bạn có thể tham khảo tại đây: http://communityuni.com/

Innovate Trading System (Kênh đầu tư lợi nhuận rất cao), các bạn nào quan tâm thì vào đây đầu tư nhé:

Chúc các bạn thành công!

Bài 31-Truy cập NodeJS RESTful Web Services bằng Android Kotlin-HTTPGET


Như vậy các Thím đã biết cách truy cập API lấy toàn bộ Product bằng HTTPGET trong Android Kotlin. Bài này ta tiếp tục truy cập API dùng method HTTP GET để lấy thông tin chi tiết của một Product.

Tiếp tục mở lại Project AndroidKotlinToNodeJS trong bài 30. Trong bài này ta đã có Custom layout có nút Edit. Bây giờ ta xử lý nhấn vào nút Edit đó thì mở màn hình thông tin chi tiết lên (lấy Mã của Product đang chọn rồi truy cập API lấy thông tin chi tiết Product, ví dụ lấy Product có mã P999: http://192.168.1.137/nodejsapi/products/P999

cụ thể, ta có hình sau:

Chi tiết các bước làm như sau:

Tạo một Activity mới tên là ChiTietActivity:

Layout XML của activity_chi_tiet.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".ChiTietActivity">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Mã Product:"
        android:textSize="20sp" />

    <EditText
        android:id="@+id/edtMa"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Tên Product:"
        android:textSize="20sp" />

    <EditText
        android:id="@+id/edtTen"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName" />
    <TextView
        android:id="@+id/textView3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Đơn giá:"
        android:textSize="20sp" />

    <EditText
        android:id="@+id/edtDonGia"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="numberDecimal" />

    <Button

        android:id="@+id/btnLuu"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Đổi thông tin"
        android:textSize="20sp" />

</LinearLayout>

Tiến hành sửa Coding ProductAdapter:

package com.communityuni.adapter

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.AsyncTask
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import com.communityuni.androidkotlintonodejs.ChiTietActivity
import com.communityuni.androidkotlintonodejs.R
import com.communityuni.model.Product


class ProductAdapter(internal var context: Activity, internal var resource: Int) : ArrayAdapter<Product>(context, resource) {

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        var custom = context.layoutInflater.inflate(resource, null)
        var txtMa = custom.findViewById<TextView>(R.id.txtMa)
        var txtTen = custom.findViewById<TextView>(R.id.txtTen)
        var txtDonGia = custom.findViewById<TextView>(R.id.txtDonGia)
        var p = getItem(position)
        txtMa.text = p!!.Ma
        txtTen.text = p.Ten
        txtDonGia.text = p.DonGia.toString()
        var img=custom.findViewById<ImageView>(R.id.imgEdit)
        img.setOnClickListener { xuLyEdit(p) }
        return custom
    }

    private fun xuLyEdit(p: Product?) {
        var i=Intent(context,ChiTietActivity::class.java)
        i.putExtra("Ma",p!!.Ma)
        context.startActivity(i)
    }
}

Coding ở trên ta bổ sung sự kiện cho ImageView, ta truyền Mã Product được chọn qua màn hình ChiTietActivity.

Bên màn hình ChiTietActivity sẽ nhận được Mã Product này mà truy cập API xem chi tiết Product là xong, Xem coding của lớp ChiTietActivity:

package com.communityuni.androidkotlintonodejs

import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.EditText
import com.communityuni.model.Product
import org.json.JSONObject
import java.net.URL

class ChiTietActivity : AppCompatActivity() {
    lateinit var edtMa:EditText
    lateinit var edtTen:EditText
    lateinit var edtDonGia:EditText
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_chi_tiet)
        addControls()
    }

    private fun addControls() {
        edtMa=findViewById(R.id.edtMa)
        edtTen=findViewById(R.id.edtTen)
        edtDonGia=findViewById(R.id.edtDonGia)
    }

    override fun onResume() {
        super.onResume()
        var ma=intent.getStringExtra("Ma")
        HTTPGetProductDetailTask().execute(ma)
    }
    inner class HTTPGetProductDetailTask : AsyncTask<String, Void, Product?>()
    {
        override fun doInBackground(vararg p0: String?): Product? {
            var p:Product?=null
            var ma=p0[0]
            try
            {
                var url=URL("http://192.168.1.137/nodejsapi/products/"+ma)
                var urlConnection=url.openConnection()
                var data = urlConnection.inputStream.bufferedReader().readText()
                var jsonObject=JSONObject(data)
                var Ma=jsonObject.getString("Ma")
                var Ten=jsonObject.getString("Ten")
                var DonGia=jsonObject.getDouble("DonGia")
                p=Product(Ma,Ten,DonGia)
            }
            catch (ex:Exception)
            {
                Log.e("LOI",ex.toString())
            }
            return p
        }
        override fun onPostExecute(result: Product?) {
            super.onPostExecute(result)
            if(result!=null)
            {
                edtMa.setText(result.Ma)
                edtTen.setText(result.Ten)
                edtDonGia.setText(result.DonGia.toString())
            }
        }
    }
}

bài 30 ta đã biết cách triệu gọi danh sách Product rồi, trong bài 31 này lại đơn giản hơn, nó chỉ trả về duy nhất 1 Product nên ta không cần vòng lặp. Mà lấy luôn từ JSonObject.

Chỗ coding này đã quen thuộc nên Tui sẽ không giải thích kỹ lại nữa vì bạn đã hiểu trong bài 30 rồi.

Như vậy ta đã hoàn thành xong bài triệu gọi Web API lấy Chi Tiết Product được viết bằng NodeJS và Deploy trên IISNode WebServer.

Source code Triệu gọi Web API lấy thông tin chi tiết Product tải ở đây.

Bài sau Tui sẽ hướng dẫn các Thím cách dùng Android Kotlin để  truy cập API RESTful Chỉnh Sửa Product như thế nào. Các bạn chú ý theo dõi nhé (vẫn dùng lại Project này)

Các khóa học online khác, bạn có thể tham khảo tại đây: http://communityuni.com/

Innovate Trading System (Kênh đầu tư lợi nhuận rất cao), các bạn nào quan tâm thì vào đây đầu tư nhé:

Chúc các bạn thành công!

 

%d bloggers like this: