使用Ruby on Rails 內建respond_to 方法匯出excel格式資料

icelandcheng
8 min readDec 31, 2018

--

網站儲存在資料庫的資料,通常用來顯示在網頁上,例如咖啡廳的資料,可能是用來顯示在地圖上,顯示咖啡廳的位置分佈,或者是用來提供使用者查詢,但有的時候,使用者可能會想取得原始的資料,例如可能想做進一步的統計分析,這時我們就可以提供使用者把資料直接打包下載,讓使用者直接拿去做進一步的應用,若是使用Ruby on Rails 來架設網站,剛好Ruby on Rails 提供了一個內建的方法respond_to,這個方法支援回應不同的資料格式,例如json, xml, csv等等,同時也支援匯出excel的.xls格式,所以我們剛好可以利用這個方法來為網站增加一個匯出excel格式資料的功能,讓更多使用者可以把我們網站所儲存的資料下載來做更多的應用,下面就來說明如何利用Ruby on Rails內建的方法respond_to來新增一個匯出excel資料的功能。

以咖啡廳分布的這個網站為例,若想讓使用者可以直接將地圖上顯示的咖啡廳資料直接下載為excel檔,首先,要加一個匯出excel資料按鈕在要匯出資料的頁面上,像下面這樣

以目前這個專案來說,因為想把按鈕放在首頁,所以可以在view/coffee/index.html這個檔案裡面,把下面的程式碼放在想要顯示匯出資料按鈕的位置

<%= link_to ‘<span class=”glyphicon glyphicon-save”
style=”color:white;” aria-hidden=”true”></span>’.html_safe, coffees_path(format: :xls, params: request.parameters), class: ‘btn’, style: ‘background-color: #555555;’, title: “匯出資料”, data: {toggle: “tooltip”, placement: “bottom”} %>

要注意的是,按鈕連結後面要帶入想要得到回應的格式,像上面加粗體的寫法那樣,後面可以再帶入request.params,這樣如果是有一些篩選功能的頁面,就可以依據篩選的結果匯出的xls檔案,按鈕連結(routes的設定)可以自己設定要指向哪一個controller 的action,可以設計一個新的action,也可使用既有的,在咖啡廳這個專案,匯出資料的按鈕是放在首頁,所以按鈕連結就直接使用導向首頁的連結,routes的設定就是指向coffee controller的index action,在config/routes.rb裡面的設定就像下面這樣

Rails.application.routes.draw do
resources :coffees
root "coffees#index"
end

再來要讓按鈕點選了以後,可以回傳所有咖啡廳資訊的excel格式檔案,所以要將respond_to方法加入按鈕連結(routes的設定)所對應的controller action ,以目前的專案就是controller/coffees_controller.rb 裡面的index action,在index action加入以下程式碼(粗體字的部分)

class CoffeesController < ApplicationController
def index
@coffees = CoffeeDatum.all
respond_to do |format|
format.html
format.xls
end

end
end

這個controller action本來就已經有把全部的咖啡廳資料撈出來,存成@coffees變數,所以我們只要在這個controller action 除了把@coffees用html回應給view之外同時也支援回應xls格式給view即可。

然後因為Ruby on Rails 預設有註冊在mime_type裡面的格式沒有xls,所以要將xls加入註冊的格式中,加入方法為,在config/initializers/mime_types.rb檔案加入以下程式碼

Mime::Type.register "application/xls", :xls

最後,因為要把資料用excel的格式匯出,這時會需要一個匯出的格式樣板,例如設定每一欄的名稱是什麼,格式樣板設定的方式為在按鈕連結(routes設定)相對應到的view底下的資料夾位置新增一個.xls.erb檔,例如在咖啡廳專案,我們設定的按鈕連結是的routes設定是“coffees#index”,所以會需要在view/coffees資料夾底下新增一個index.xls.erb檔,檔案裡面的程式碼可以像下面這樣,可以設定匯出的檔案名稱,然後每欄的欄位名稱,然後對應的咖啡廳屬性資料

<?xml version='1.0'?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Coffees">
<Table>
<Row>
<Cell><Data ss:Type="String">咖啡店名</Data></Cell>
<Cell><Data ss:Type="String">地址</Data></Cell>
<Cell><Data ss:Type="String">緯度</Data></Cell>
<Cell><Data ss:Type="String">經度</Data></Cell>
<Cell><Data ss:Type="String">開始營業時間</Data></Cell>
</Row>
<% @coffees.each do |cof| %>
<Row>
<Cell><Data ss:Type="String"><%= cof.name %></Data></Cell>
<Cell><Data ss:Type="String"><%= cof.add %></Data></Cell>
<Cell><Data ss:Type="String"><%= cof.lat %></Data></Cell>
<Cell><Data ss:Type="String"><%= cof.lon %></Data></Cell>
<Cell><Data ss:Type="String"><%= cof.time %></Data></Cell>
</Row>
<% end %>
</Table>
</Worksheet>
</Workbook>

以上都設定好了以後,開啟頁面,點選匯出資料按鈕,應該就可以順利下載到一個名為coffees的.xls檔案

打開之後內容應該會像下面這樣,包含了我們在index.xls.erb設定的欄位標題以及資料內容

以上就是簡單以Ruby on Rails內建的respond_to 方法在展示咖啡廳分布的網站簡單新增一個匯出excel資料(.xls)的功能的製作方法,同樣的方式應該也適用於多數以Ruby on Rails建構的網站。

參考資料:

Rails 中的 MIME 类型解析规则

Ruby on Rails 實戰聖經 — respond_to

--

--

icelandcheng
icelandcheng

Written by icelandcheng

Programming Skill learner and Sharer | Ruby on Rails | Golang | Vue.js | Web Map API

No responses yet