1. 程式人生 > >web列印元件康虎雲報表與odoo整合示例

web列印元件康虎雲報表與odoo整合示例

康虎雲報表是最好用的web列印元件之一,而Odoo(前身為OpenERP)則是最好的開源ERP,把康虎雲報表與odoo整合,實現odoo報表精準輸出,複雜報表快速開發,這個任務我籌劃很久了,也已經拖了很久了,昨天終於抽出時間給一班兄弟講解了一下,講的過程中氣氛還不錯,可惜的是錄視訊時,聲音沒錄下來,成了啞劇。這兩天要抽時間再錄一段。
康虎雲報表與odoo整合,原理其實很簡單,就是在odoo原有報表基礎上或者新建報表,把原來用QWeb輸出的報表內容,轉換成符合康虎雲報表的json資料。在這個轉換過程中,如果是簡單欄位,是很方便的,用<t t-esc=”…”>即可輸出不帶html標籤的數值;而對於one2many、many2many等關聯欄位,最簡便的辦法就是利用Qweb引擎自身的功能把關聯欄位值取出來,即t-field標籤。但t-field標籤有個問題,它生成的值帶有多重HTML標籤,不僅容易造成json出現語法錯誤,也不易在康虎雲報表中使用,因此如何生成不帶HTML標籤的值(姑且稱之為 raw值)是轉換的關鍵。
通過對QWeb底層渲染機制的研究,想出一種辦法,在欄位值最終輸出前呼叫自定義函式移除HTML標籤,只保留內容,目前這個功能已經做成通用功能,內建在 cfprint這個模組中,要在odoo中使用康虎雲報表,需要先安裝這個模組。然後對Qweb報表進行簡單改造,插入生成json的程式碼。這次使用的是對倉庫收貨功能的一個小擴充套件,列印“入庫核對單”,即倉管在收貨前先列印“入庫核對單”,然後根據核對單上的商品一個個清點,把實際清點的資料填寫到表格裡,在然後在odoo收貨單裡填上實際收貨數量。
如何開發一個odoo模組並建立一個QWeb報表就不贅述了,大家自己去網上搜索,這裡只貼出對Qweb報表的改造部分。在QWeb報表程式碼中,在模板底部找到

  1. </template>

標籤,然後在該標籤上一行插入如下的程式碼:

  1. <!--必須先安裝cfprint模組,以引入基礎類庫-->
  2. <scripttype="text/javascript">
  3. var cfprint_addr ="127.0.0.1";//列印伺服器監聽地址
  4. var _delay_close =-1;//列印完成後關閉視窗的延時時長(毫秒), -1則表示不關閉
  5. var _tablePack ={
  6. "Name":"Pack",
  7. "Cols":[
  8. {"type":"str","size":255,"name":"倉庫","required":false},
  9. {"type":"str"
    ,"size":50,"name":"供應商","required":false},
  10. {"type":"str","size":30,"name":"日期","required":false},
  11. {"type":"str","size":255,"name":"入庫單號","required":false},
  12. {"type":"str","size":30,"name":"採購單號","required":false},
  13. {"type":"int","size":0,"name":"件數","required":false},
  14. {"type":"str","size":20,"name":"包裝種類","required"
    :false},
  15. {"type":"str","size":30,"name":"車號","required":false},
  16. {"type":"str","size":30,"name":"櫃號","required":false}
  17. ],
  18. "Data":[]
  19. };
  20. var _tablePackLines ={
  21. "Name":"PackLines",
  22. "Cols":[
  23. {"type":"str","size":30,"name":"入庫單號","required":false},
  24. {"type":"str","size":255,"name":"產品","required":false},
  25. {"type":"str","size":30,"name":"條形碼","required":false},
  26. {"type":"float","size":0,"name":"採購數量","required":false},
  27. {"type":"float","size":0,"name":"實際數量","required":false},
  28. {"type":"str","size":20,"name":"計量單位","required":false},
  29. ],
  30. "Data":[]
  31. };
  32. <t t-foreach="docs" t-as="o">
  33. /*生成主表資料*/
  34. _tablePack.Data.push(
  35. {
  36. "倉庫":"<span t-field="o.picking_type_id.warehouse_id.partner_id" t-field-options='{"widget": "contact", "fields": ["name"], "no_marker": true, "no_tag_br": true, "data_type": "raw"}' />",
  37. "供應商":"<t t-if="o.partner_id" name="partner_header"><span t-field="o.partner_id" t-field-options='{"widget": "contact", "fields": ["name"], "no_marker": true, "no_tag_br": true, "data_type": "raw"}' /></t>",
  38. "日期":"<t t-esc="context_timestamp(datetime.datetime.now()).strftime('%Y-%m-%d %H:%M')"/>",
  39. "入庫單號":"<t t-esc="o.name" class="mt0"/>",
  40. "採購單號":"<t t-if="o.origin"><t t-esc="o.origin"/></t>",
  41. "件數":"<t t-esc="sum(pack_operation.product_qty for pack_operation in o.pack_operation_ids)"/>",
  42. "包裝種類":"",
  43. "車號":"",
  44. "櫃號":""
  45. });
  46. <t t-foreach="o.pack_operation_ids" t-as="pack_operation">
  47. /*生成從表資料*/
  48. _tablePackLines.Data.push(
  49. {
  50. "入庫單號":"<t t-esc="o.name" class="mt0"/>",
  51. "產品":"<span t-field="pack_operation.product_id" t-options='{"data_type":"raw"}'/>",
  52. "條形碼":"<t t-if="pack_operation.product_id and pack_operation.product_id.barcode"><span t-field="pack_operation.product_id.barcode" t-field-options='{"data_type":"raw"}'/></t>",
  53. "採購數量":"<t t-esc="pack_operation.product_qty"/>",
  54. "實際數量":"",
  55. "計量單位":"<span t-field="pack_operation.product_uom_id" t-options='{"data_type":"raw"}'/>"
  56. });
  57. </t>
  58. </t>
  59. /*資料合併到總的資料物件*/
  60. var _data ={"template":"warehouse_checklist.fr3","ver":4,"Copies":1,"Duplex":0,"Tables":[]};
  61. _data["Tables"].push(_tablePack);
  62. _data["Tables"].push(_tablePackLines);
  63. var _reportData = JSON.stringify(_data);//轉成json字串
  64. console.log(_reportData);
  65. //生成資料之後,在cfprint_ext.js中會自動呼叫進行列印
  66. </script>

細心的使用者可能會發現,在

  1. <spant-field="pack_operation.product_id"t-options='{"data_type":"raw"}'/>"

裡有一個t-options='{“data_type”:”raw”}’,這正是我們對t-field標籤的擴充套件,以輸出raw值。
在QWeb報表中插入上面程式碼之後,還需要把報表型別由pdf改為html才可以。具體是在報表定義中進行修改(也可以通過介面修改,不過通過介面修改的話,重灌或升級模組報表型別就恢復成PDF了)。具體修改如下:

  1. <report
  2. string="Warehouse Checklist"
  3. id="action_report_warehouse_checklist"
  4. model="stock.picking"
  5. report_type="qweb-html" ###這個地方由qweb-pdf改成為 qweb-html
  6. name="stock_cf.report_warehouse_checklist"
  7. file="stock_cf.report_warehouse_checklist"
  8. />

改造完成後,把康虎雲報表解壓到任意目錄(例如:康虎雲報表系統_ver1.3.7.3),執行cfprint\cfprint.exe程式並保持執行狀態。把預先設計好的報表模板(stock_cf\cfprint_template\warehouse_checklist.fr3)複製到康虎雲報表安裝目錄(cfprint.exe所在目錄)。
重新安裝或升級stock_cf模組,然後進入倉庫管理,如果有待收貨記錄,選擇一條收貨記錄(如果沒有,就新建一個採購訂單並確認),然後按“列印”–>“入庫核對單”,如果不出意外,康虎雲報表就會接收到列印請求並向印表機輸出報表。如果沒有輸出,建議開啟瀏覽器的javascript控制檯,看看有什麼出錯資訊,並根據出錯資訊進行修改除錯。
以上就是康虎雲報表與odoo的整合工作,以後就只需要按此步驟操作即可。