Hiển thị đồ hoạ trên Web sử dụng Excel và Trình duyệt Web

Với sự tiến hoá của công nghệ Web, nhu cầu tǎng cường các tính nǎng cho các ứng dụng Web cũng tǎng lên không ngừng. Không chỉ đơn thuần dựa vào ngôn ngữ đánh dấu vǎn bản đơn giản như HTML, một dạng yêu cầu mới về khả nǎng xây dựng các biểu đồ "đồ hoạ" dựa trên số liệu tác nghiệp trong cơ sở dữ liệu đã xuất hiện. "Một bức tranh có giá trị hơn hàng nghìn từ". Giá trị của một biểu đồ hay đồ thị trình bày thật là to lớn, do vậy chúng ta hãy đi sâu vào các phương pháp khác nhau để tiến tới đạt được mục tiêu đó. Bài viết không chỉ giải thích mục đích và sức mạnh của công nghệ đặc thù mà còn bao gồm cả một ví dụ hoàn chỉnh bằng cách thiết kế từng bước theo quan điểm người sử dụng và nhà phát triển.

Mở đầu

Với sự tiến hoá của công nghệ Web, nhu cầu tǎng cường các tính nǎng cho các ứng dụng Web cũng tǎng lên không ngừng. Không chỉ đơn thuần dựa vào ngôn ngữ đánh dấu vǎn bản đơn giản như HTML, một dạng yêu cầu mới về khả nǎng xây dựng các biểu đồ "đồ hoạ" dựa trên số liệu tác nghiệp trong cơ sở dữ liệu đã xuất hiện. "Một bức tranh có giá trị hơn hàng nghìn từ". Giá trị của một biểu đồ hay đồ thị trình bày thật là to lớn, do vậy chúng ta hãy đi sâu vào các phương pháp khác nhau để tiến tới đạt được mục tiêu đó.

Có nhiều cách khác nhau để đạt được cùng một mục đích - Các trình điều khiển khách ActiveX và các Java applets được quy về cùng một dạng. Chúng ta sẽ xem xét cách và ưu điểm mà nó mang lại. Sử dụng Visual Basic 6 chúng ta sẽ phát triển thành phần chủ (server-side) như là một ActiveX DLL. Thành phần này sẽ bao hàm các khả nǎng đồ hoạ của MS Excel cung cấp các khả nǎng đó cho các nhà phát triển/người sử dụng VB/ASP theo cách hết sức đơn giản. Các biểu đồ sẽ được khởi tạo trên các ứng dụng chủ (server) sử dụng MS Excel và sau đó được xuất tới một tệp GIF đơn giản ở vị trí mong muốn trên máy chủ. Một khi tệp GIF đã sẵn sàng nó có thể được tải về trình máy khách dưới dạng mã HTML đơn giản như sau:

<IMG SRC=ExcelChart.GIF>

Bài viết không chỉ giải thích mục đích và sức mạnh của công nghệ đặc thù mà còn bao gồm cả một ví dụ hoàn chỉnh bằng cách thiết kế từng bước theo quan điểm người sử dụng và nhà phát triển.

Để mô tả rõ hơn, chúng ta sẽ cung cấp các mã nguồn của thành phần có các khả nǎng xây dựng biểu đồ của MS Excel từng bước thông qua ngôn ngữ kịch bản và ngôn ngữ HTML đơn giản. DLL này là một thành phần ActiveX khá nhỏ, chỉ khoảng 50K.

Các yêu cầu ban đầu

Chỉ sử dụng trình duyệt (browser) trên máy khách (như Internet explorer hay Netscape Navigotor), còn các chức nǎng sẽ chạy trên Web server. Các thành phần sẽ được lưu ở trên máy chủ và do vậy các trình duyệt khách sẽ không phải tải về (download) hoặc đǎng ký các thành phần đó trên máy trạm. Hơn nữa, không cần các điều khiển ActiveX đặc biệt nào hay các Java applet trên chạy trên máy khách. Kết quả nhận được sẽ là một tệp GIF đơn chứa biểu đồ (dù rất phức tạp) và toàn bộ quá trình sinh ra biểu đồ này diễn ra trên máy chủ web server.

Định cấu hình máy chủ Server

� Microsoft Excel 2000 phải được cài đặt trên Server.
� Tệp DLL chứa thành phần ExcelChart phải được sao (copy) vào Server (tệp ExcelChart.DLL) và được đǎng ký sử dụng tiện ích regsvr32. Câu lệnh để đǎng ký là: regsvr32 C:\directory_path\ExcelChart.dll
� Thiết đặt quyền đọc (Read) trên file DLL. Tài khoản Windows NT dùng để truy nhập là tài khoản người sử dụng nặc danh (anonymous), trên Windows NT là tài khoản IUSR_machinename.
� Thư mục mà tệp GIF sẽ được xuất ra phải có quyền ghi (Write) trên NTFS.

Môi trường hoạt động: Công cụ và Phần mềm

Để thực hiện ví dụ này, ta cần phải có:
� NT 4.0 (SP 5)
� IIS 4.0
� SQL Server 7 (nguồn dữ liệu cho biểu đồ)
� MS Office 2000
� ExcelChart.DLL
� IE 5.0
� Visual Interdev và Visual Basic 6 (các công cụ phát triển)

Bước 1: Máy khách cung cấp các tham biến để tập hợp dữ liệu

Đây là bước tùy chọn phụ thuộc vào ứng dụng và thường là một biểu mẫu (form) HTML đơn giản. Ví dụ, bạn cần biểu đồ số liệu 5 nǎm của một nhà máy sản xuất, như được minh hoạ trong mã nguồn sau đây. Phần đầy đủ của đoạn mã nguồn có thể tìm thấy trong tệp DataForChart.htm kèm theo bài viết này.

Biểu mẫu sẽ lấy thời gian là 5 nǎm và tên nhà máy sẽ được lấy ra từ hộp chọn với một cờ kiểm tra phụ ở trong hộp kiểm tra. Cờ này đặc tả có hay không sử dụng dữ liệu từ RDBMS của bạn hay bạn tự xây dựng lấy một Recordset bằng các mã kịch bản. Biểu mẫu gửi thông báo tới tệp BuildAndShowChart.asp để thực hiện các công việc còn lại.
<FORM METHOD=POST ACTION="BuildAndShowChart.asp">
<P>
<H2>Step 1: Client feeds parameters for collection of data</H2>
<P>Specify the five year period for chart
<SELECT id=iYear name=iYear>
<OPTION VALUE=1991>1991 - 1995</OPTION>
<!- further options go here ->
<OPTION VALUE=2000>2000 - 2004</OPTION>
</SELECT>
<P>Specify the factory
<SELECT id=strFactory Name=strFactory>
<OPTION VALUE='FACTORY 1'>Factory 1</OPTION>
<OPTION VALUE='FACTORY 2'>Factory 2</OPTION>
</SELECT>


Kiểm tra hộp thoại này nếu cơ sở dữ liệu không có mặt, một Recordset sẽ được xây dựng qua các mã kịch bản

<INPUT type="checkbox" id=chbRSMode name=chbRSMode>
...
<INPUT Name=Submit TYPE=SUBMIT VALUE=Submit>
</FORM>
INCLUDEPICTURE "http://thang05/asptoday/aspfolder/images/20000303_1.gif" \* MERGEFORMATINET

Bước 2: Kịch bản ASP tiến hành xử lý các tham số từ biểu mẫu

Biểu mẫu gửi thông báo tới trang ASP BuildAndShowChart.asp. Đây là phần cốt lõi sử dụng thành phần liên quan. Tệp kịch bản tiến hành xử lý các tham số được gửi từ biểu mẫu gửi tới nó.
<%
Dim iStartYear, iEndYear
Dim strFactory, strRSMode
Dim flgRSFromDatabase

'-- đọc nǎm bắt đầu để Submit từ biểu mẫu
iStartYear = Request.Form( "iYear" )
if( IsEmpty(iStartYear) or IsNull(iStartYear)) then iStartYear = 1991

'-- tính nǎm kết thúc dựa vào nǎm bắt đầu
iEndYear = CInt(iStartYear)+4

'-- nhận tên nhà máy mà sản phẩm được hiển thị
strFactory = Request.Form( "strFactory" )
If( IsEmpty(strFactory) Or IsNull(strFactory)) Then strFactory = "FACTORY 1"

'-- xác định rõ nếu dữ liệu được chọn lọc từ cơ sở dữ liệu, hình thức Recordset
strRSMode = Request.Form( "chbRSMode" )

'-- flgRSFromDatabase = false nghĩa là xây dựng Recordset qua kịch bản mà không có cơ sở dữ liệu
If (Not IsEmpty(strRSMode) And Not IsNull(strRSMode) And strRSMode = "on" )
Then flgRSFromDatabase = False
Else flgRSFromDatabase = True
%>

Một vài dòng mã đầu tiên đọc nǎm bắt đầu, gán cho nó với một giá trị mặc định là nǎm 1991 nếu biểu mẫu không cung cấp nǎm bắt đầu. Nǎm kết thúc được tính toán sử dụng nǎm đầu tiên. Tương tự tên nhà máy cũng được xác định.

Giá trị từ hộp kiểm tra được đọc và vì vậy mà flgRSFromDatabase được xác định rõ. Cờ này được thiết đặt là True nếu Recordset đã được thiết kế đặc biệt từ cơ sở dữ liệu trong RDBMS của bạn. Nói cách khác, một Recordset tạm thời được thiết kế qua các kịch bản. Quá trình xây dựng một Recordset bằng mã kịch bản trong đoạn tiếp theo tỏ ra rất thuận tiện.

Mặc dầu có nhiều người muốn sử dụng nguồn dữ liệu tạo sẵn, nguồn dữ liệu đã phải được chuẩn bị. Bạn cần một cơ sở dữ liệu mẫu - CHARTDATA với một bảng được đặt tên là yearly_production.

Bảng này sẽ chứa 3 trường - factory_name, production_year, production_in_tons. Chúng ta cung cấp một kịch bản là create_production_table.sql để tạo bảng trong MS SQL Server và nhập vào nó với một vài dữ liệu mẫu. Sau đó hình thức tổng hợp dữ liệu sẽ xác định rõ đoạn tới của kịch bản sẽ hiển thị mức dưới cho phép ta chuẩn bị với các Recordset.

Bước 3: Chuẩn bị dữ liệu cho biểu mẫu Recordset

Trang ASP BuildAndShowChart.asp xây dựng Recordset. Mô tả đối tượng kết nối (Connection) và nhận dữ liệu trong biểu mẫu chứa Recordset là một kỹ thuật phổ biến trong lập trình ngôn ngữ ASP. Kịch bản sau đây được chia ra làm hai phần tách biệt nhau. Phần đầu tiên chuẩn bị một Recordset sử dụng dữ liệu có sẵn từ RDBMS của bạn dùng một xâu truy vấn đã chuẩn bị với các tham số nhận được từ biểu mẫu. Phần hai tạo một đối tượng Recordset trực tiếp với cấu trúc của các trường theo yêu cầu, bằng cách này bạn không cần phải có một mối liên kết với một cơ sở dữ liệu đã sẵn sàng chuẩn bị từ trước.

<%
Dim oRs
Dim oConnection
Dim strQuery

'-- preparing recordset from database
if( flgRSFromDatabase = true ) then
'-- tạo đối tượng Connection
Set oConnection = Server.CreateObject ("ADODB.Connection" )

'--mở connection
oConnection.Open "Driver={SQL Server}; Server=(local); Database=CHARTDATA;
UID=sa; PWD=sa"

'-- xây dựng câu truy vấn
strQuery = "SELECT * FROM yearly_production WHERE factory_name='" +
strFactory + "' AND production_year BETWEEN " + CStr(iStartYear)
+ " AND " + CStr(iEndYear)
'-- get the data in recordset
Set oRs = oConnection.Execute( strQuery )

'-- kiểm tra nếu có dữ liệu
if( oRs.EOF ) then
Response.Write( "No data available" )
Response.End
end if
'-- prepare recordset through scripting instead of actual database
else
'-- tạo đối tượng recordset
Set oRs = Server.CreateObject("ADODB.Recordset" )

with oRs
.CursorLocation = 3 '-- client-side cursor
with .Fields
.Append "factory_name", adVarChar, 25
.Append "production_year",adInteger
.Append "production_in_tons",adInteger
end with

.Open '-mở recordset

'-- thêm các bản ghi
..AddNew Array("factory_name","production_year", "production_in_tons"), _
Array(strFactory, iStartYear, "50")
.AddNew Array("factory_name","production_year", "production_in_tons"), _
Array(strFactory, iStartYear+1, "160")
..AddNew Array("factory_name","production_year", "production_in_tons"), _
Array(strFactory, iStartYear+2, "90")
..AddNew Array("factory_name","production_year", "production_in_tons"), _
Array(strFactory, iStartYear+3, "120")
..AddNew Array("factory_name","production_year", "production_in_tons"), _
Array(strFactory, iStartYear+4, "200")

'-- cập nhật
.Update
end with
end if
%>

Đầu tiên cấu trúc trường yêu cầu được tạo trong tập hợp các trường Fields sử dụng phương thức Append(). 5 hàng được chèn thêm vào sử dụng phương thức AddNew() của đối tượng Recordset. Cuối cùng phương thức Update() hoàn thành quy trình trên và các recordset đã bắt đầu sẵn sàng. Để biết thêm thông tin về đối tượng ADO Recordset các bạn có thể tham khảo thêm từ thư viện trợ giúp MSDN của Microsoft.
Lưu ý là cách thức đưa ra khi sử dụng quy trình này luôn luôn giữ lại các hằng số, chúng ta sẽ không phải sử dụng việc sinh ngẫu nhiên nào.

Thứ Ba, 24/02/2004 03:20
31 👨 548
0 Bình luận
Sắp xếp theo
    ❖ Tổng hợp