iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0

Hi,大家好,關於side projects ,已經進入尾聲了,我們完成了資料的輸入、顯示,今天要來完成報表製作的功能。那麼讓我們開始吧

報表的用途

一般的系統規劃中,如果有需要列印的需求,多數都是頁面直接印出,但是直接印出的情形,會發現頁面顯示的排列、顏色等與印表機會有不同,因此在商用軟體上,要就是另外設定列印的樣式,或是直接引入商用報表工具來產製報表,因為使用報表工具,具有較容易控制版面、加入總頁數顯示…等功能,因此我通常是使用報表工具來處理列印的需求

報表製作說明

在不少商用軟體都會有所謂的報表產生的功能,例如說 .NET平台的 crystal report、jsp平台常用的 Jasper report,都是可以產生商用報表的工具,本身功能強大,可以應付絕大多數的商用情況,但是因為多數都是要另外學習新的報表工具的用法,所以我們這邊採用了另一個簡單 jsreport 來製作報表,該軟體可以做到將 html 渲染成為 pdf,因此對前端人員來說,幾乎沒有學習門檻

安裝

使用該工具,需連結至 jsreport官網 下載並安裝,可支援各種平台,依照執行環境下載對應的平台即可,安裝完畢後,報表會使用 5488 port 啟動

報表檔製作

報表檔為一般之 html 檔,要傳入資料時可使用 {{參數欄位}} 傳,若要印出陣列中的資料,可以 each 來處理,報表內容如下

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <style>
        .page-break {
            display: block;
            page-break-before: always;
        }

        page[size="A4"] {
            background: white;
            width: 21cm;
            height: 29.7cm;
            display: block;
            margin: 0 auto;
            margin-bottom: 0.5cm;
            box-shadow: 0 0 0.0cm rgba(0, 0, 0, 0);
        }

        @media print {

            body,
            page[size="A4"] {
                margin: 0;
                box-shadow: 0;
            }
        }


        @font-face {
            font-family: 'EUDC';
            font-style: normal;
            font-weight: 500;
            src: url('//220.130.182.55/fonts/eudc_With_mingliu.woff'),
                url('//220.130.182.55/fonts/eudc_With_mingliu.woff') format('woff'),
                url('//220.130.182.55/fonts/eudc_With_mingliu.ttf') format('truetype');
        }

        * {
            font-family: 'EUDC';
            font-size: 14px;
        }
    </style>
</head>

<body>

    
    <div class="container">
        <div class="row">
            <div class="col-12" style="padding-top: 10px;">
                <style>
  .tr {
    border-top: 1pt solid green;
  }

  .dr {
    border-left: 1pt solid green;
    border-right: 1pt solid green;
    ;
  }

  .title {
    background-color: rgb(152, 253, 152);
    border-bottom: 1px solid green;
  }

  .info {
    background-color: rgb(202, 255, 202);
    border-bottom: 1px solid green;
  }

  .txtr {
    text-align: right;
  }

  .inpcc {
    background-color: lightyellow;
    color: orange;
    border-bottom: 1px solid green;
  }

  .tc {
    text-align: center;
  }
</style>
<div id="app" class="container">
  <h3>問題描述</h3>
  <div class="row dr tr">
    <div class="col-2 title txtr">問題名稱:</div>
    <div class="col-10">{{cases.casedesc}}</div>
  </div>
  <div class="row dr">
    <div class="col-2 title txtr">問題描述:</div>
    <div class="col-10">{{cases.caseinfo}}</div>
  </div>
  <div class="row dr">
    <div class="col-2 title txtr">聯絡人:</div>
    <div class="col-6">{{cases.fromper}} <a
        href="mailto://{{cases.frommail}}">{{cases.frommail}}</a></div>
    <div class="col-2 title txtr">聯絡電話:</div>
    <div class="col-2">{{cases.fromtel}}</div>
  </div>
  <div class="row dr">
    <div class="col-2 title txtr">登錄時間:</div>
    <div class="col-8">{{cases.logdate}}</div>
    <div class="col-2">{{cases.casestatus_desc}}</div>
  </div>
  <hr />
    <h3>辦理情形</h3>
	{{#each cases.circuits}}
    <div class="row ">
      <div class="col-2">{{flowsdate}}</div>
      <div class="col-2">{{userid}}</div>
      <div class="col-5">{{flowdesc}}</div>
      <div class="col-2">{{status_desc}}</div>
    </div>
	{{/each}}
</div>

將檔案儲在routers/report/report.html

呼叫報表

最後在 router中新增產出報表的功能,本次範例假設報表是安裝在本機上,因此呼叫jsreport-client,直接指定 127.0.0.1


router.get("/report/:guid", async (req, res, next) => {
    try {
        let guid = req.params.guid
        //讀取資料
        let result = await casedao.getSingleCase(guid)
        //讀取報表檔案
        let report = fs.readFileSync(path.join(__dirname, "report", "report.html"))
        // 取報表檔範例
        const jsreport = require('jsreport-client')(
            "127.0.0.1", "", "");
        jsreport.render({
            template: {
                content: report,
                engine: 'handlebars',
                recipe: 'phantom-pdf',
                phantom: {
                    //直印
                    orientation: "portrait",
                    //頁面大小
                    format: "A4" //改A4直印
                }
            },
            data: result
        }, function (err, out) {
            if (err != null) {
                console.log(err)
            } else {
                res.writeHead(200, {
                    'Content-Type': "application/pdf",
                    "Content-Disposition": "inline;filename=report.pdf",
                });
                out.pipe(res);
            }
        });
    } catch (err) {
        res.status(500).send(err.message || err)
    }
})

上一篇
加入流程控管機制
下一篇
資訊安全處理機制
系列文
以vue.js + node.js 搭建一個客服填單系統30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言