整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          使用Select.HtmlToPdf 把html內(nèi)容生成pdf文件

          .NET的SelectPdf Html到Pdf轉(zhuǎn)換器-社區(qū)版是.NET的SelectPdf庫中提供的功能強(qiáng)大的html到pdf轉(zhuǎn)換器的免費(fèi)版本。
          轉(zhuǎn)換器提供了許多強(qiáng)大的選項(將任何網(wǎng)頁轉(zhuǎn)換為pdf,將任何html字符串轉(zhuǎn)換為pdf,html5 / css3 / javascript支持,頁眉和頁腳支持等),唯一的限制是它最多可以生成pdf文檔。5頁長。
          .NET的免費(fèi)HTML至Pdf轉(zhuǎn)換器–社區(qū)版功能:最多生成5頁pdf文檔,將任何網(wǎng)頁轉(zhuǎn)換為pdf,將任何原始html字符串轉(zhuǎn)換為pdf,設(shè)置pdf頁面設(shè)置(頁面大小,頁面方向,頁面邊距) ,在轉(zhuǎn)換過程中調(diào)整內(nèi)容大小以適合pdf頁面,設(shè)置pdf文檔屬性,設(shè)置pdf查看器首選項,設(shè)置pdf安全性(密碼,權(quán)限),設(shè)置轉(zhuǎn)換延遲和網(wǎng)頁導(dǎo)航超時,自定義頁眉和頁腳,在頁眉中支持html和頁腳,自動和手動分頁符,在每個頁面上重復(fù)html表頭,支持@media類型屏幕和打印,支持內(nèi)部和外部鏈接,基于html元素自動生成書簽,支持HTTP標(biāo)頭,支持HTTP cookie,支持需要身份驗證的網(wǎng)頁,支持代理服務(wù)器,啟用/禁用javascript,修改顏色空間,多線程支持,HTML5 / CSS3支持,Web字體支持等等。


          代碼實現(xiàn)

          1、nuget 引用

          Install-Package Select.HtmlToPdf

          2、方法

          • using SelectPdf;using System.Collections.Specialized;using System.IO;using System.Web;
            namespace BQoolCommon.Helpers.File{ public class WebToPdf { public WebToPdf() { //SelectPdf.GlobalProperties.LicenseKey = "your-license-key"; }
            /// <summary> /// 將 Html 轉(zhuǎn)成 PDF,並儲存成檔案 /// </summary> /// <param name="html">html</param> /// <param name="fileName">絕對路徑</param> public void SaveToFileByHtml(string html, string fileName) { var doc = SetPdfDocument(html); doc.Save(fileName); }
            /// <summary> /// 傳入 Url 轉(zhuǎn)成 PDF,並儲存成檔案 /// </summary> /// <param name="url">url</param> /// <param name="fileName">絕對路徑</param> /// <param name="httpCookies">Cookies</param> public void SaveToFileByUrl(string url, string fileName, NameValueCollection httpCookies) { var doc = SetPdfDocument(url, httpCookies); doc.Save(fileName); }
            /// <summary> /// 將 Html 轉(zhuǎn)成 PDF,並輸出成 byte[] 格式 /// </summary> /// <param name="html">html</param> /// <returns></returns> public byte[] GetFileByteByHtml(string html) { var doc = SetPdfDocument(html); return doc.Save(); }
            /// <summary> /// 傳入 Url 轉(zhuǎn)成 PDF,並輸出成 byte[] 格式 /// </summary> /// <param name="url">url</param> /// <param name="httpCookies">Cookies</param> /// <returns></returns> public byte[] GetFileByteByUrl(string url, NameValueCollection httpCookies) { var doc = SetPdfDocument(url, httpCookies); return doc.Save(); }
            /// <summary> /// 將 Html 轉(zhuǎn)成 PDF,並輸出成 Stream 格式 /// </summary> /// <param name="html">html</param> /// <returns></returns> public Stream GetFileStreamByHtml(string html) { var doc = SetPdfDocument(html); var pdfStream = new MemoryStream();
            doc.Save(pdfStream); pdfStream.Position = 0;
            return pdfStream; }
            /// <summary> /// 傳入 Url 轉(zhuǎn)成 PDF,並輸出成 Stream 格式 /// </summary> /// <param name="html">html</param> /// <returns></returns> public Stream GetFileStreamByUrl(string url, NameValueCollection httpCookies) { var doc = SetPdfDocument(url, httpCookies); var pdfStream = new MemoryStream();
            doc.Save(pdfStream); pdfStream.Position = 0;
            return pdfStream; }
            private PdfDocument SetPdfDocument(string html) { var converter = new HtmlToPdf();
            converter.Options.WebPageWidth = 1200; html = HttpUtility.HtmlDecode(html);
            return converter.ConvertHtmlString(html); }
            private PdfDocument SetPdfDocument(string url, NameValueCollection httpCookies) { var converter = new HtmlToPdf(); converter.Options.WebPageWidth = 1200;
            if (httpCookies != && httpCookies.Count != 0) { converter.Options.HttpCookies.Add(httpCookies); }
            return converter.ConvertUrl(url); }
            }}

            3、調(diào)用

            • /// <summary> /// 下載pdf /// </summary> public void Downpdf(string data) { var stream = new BQoolCommon.Helpers.File.WebToPdf().GetFileStreamByHtml(Gethtml(data)); Response.Clear(); //二進(jìn)制流數(shù)據(jù)(如常見的文件下載) Response.ContentType = "application/octet-stream"; //通知瀏覽器下載文件而不是打開 Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode("Profit and Loss Statement.pdf", System.Text.Encoding.UTF8)); var bytes = StreamToBytes(stream); Response.BinaryWrite(bytes); Response.Flush(); stream.Close(); stream.Dispose();
              Response.End(); }

              那么如何獲取指定頁面的html 呢 傳入對應(yīng)的model 獲得指定動態(tài)的html

              • private string Gethtml(string data) { string str = "";
                str = this.ControllerContext.RenderViewToString("ProfitDetails", data);
                return str; }
                • using BQoolCommon.Helpers.Format;using Newtonsoft.Json;using OrdersManager.Models.ViewModel.Report;using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Web;using System.Web.Mvc;
                  namespace OrdersManager.Web.Infrastructure{ public static class HelperExtensions { public static string RenderViewToString(this ControllerContext context, string viewName, string data) { if (string.IsOrEmpty(viewName)) viewName = context.RouteData.GetRequiredString("action");
                  context.Controller.ViewData.Model = JsonConvert.DeserializeObject<ProfitDetailsmodel>(StringTools.Base64Decode(StringTools.Base64Decode(data)));
                  using (var sw = new StringWriter()) { ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(context, viewName); var viewContext = new ViewContext(context, viewResult.View, context.Controller.ViewData, context.Controller.TempData, sw); try { viewResult.View.Render(viewContext, sw); } catch (Exception ex) { throw; }
                  return sw.GetStringBuilder().ToString(); } } }}

                  參考文檔

                  https://www.nuget.org/packages/Select.HtmlToPdf/

           前言

            導(dǎo)出Excel文件這個功能,通常都是在后端實現(xiàn)返回前端一個下載鏈接,但有時候我們只想導(dǎo)出前端頁面上已經(jīng)有了的數(shù)據(jù),不想再調(diào)后端導(dǎo)出接口浪費(fèi)服務(wù)器資源,學(xué)習(xí)本文demo例子,我們踹掉后端,直接在前端導(dǎo)出Excel!

            代碼實現(xiàn)

            1、利用Blob對象構(gòu)造一個a標(biāo)簽的href鏈接,從而實現(xiàn)文件下載,Excel支持html格式,因此我們只需要將構(gòu)造好的html內(nèi)容放到Blob對象中,即可下載Excel表格

            2、利用base64編碼構(gòu)造一個a標(biāo)簽的href鏈接,從而實現(xiàn)文件下載,同上,我們需要將構(gòu)造好的html內(nèi)容URI編碼拼到base64鏈接,即可下載Excel表格

              //blob、base64轉(zhuǎn)文件下載,通過A標(biāo)簽?zāi)M點(diǎn)擊,設(shè)置文件名
              /*
                  萬能流  application/octet-stream
                  word文件  application/msword
                  excel文件  application/vnd.ms-excel
                  txt文件  text/plain
                  圖片文件  image/png、jpeg、gif、bmp
               */
              function downloadByBlob(fileName, text) {
                  let a = document.createElement("a");
                  a.href = URL.createObjectURL(new Blob([text], {type: "application/octet-stream"}));
                  a.download = fileName || 'Blob導(dǎo)出測試.txt';
                  a.click();
                  a.remove();
                  URL.revokeObjectURL(a.href);
              }
              function downloadByBase64(fileName, text) {
                  let a = document.createElement('a');
                  a.href = 'data:application/octet-stream;base64,' + window.btoa(unescape(encodeURIComponent(text)));
                  a.download = fileName || 'Base64導(dǎo)出測試.txt';
                  a.click();
                  a.remove();
                  URL.revokeObjectURL(a.href);
              }

            封裝導(dǎo)出Excel表格方法

              //踹掉后端,前端導(dǎo)出Excel!
              function exportExcel(fileName,columns,datas){
                  //列名
                  let columnHtml = "";
                  columnHtml += "<tr style=\"text-align: center;\">\n";
                  for (let key in columns) {
                      columnHtml += "<td style=\"background-color:#bad5fd\">"+columns[key]+"</td>\n";
                  }
                  columnHtml += "</tr>\n";
          
                  //數(shù)據(jù)
                  let dataHtml = "";
                  for (let data of datas) {
                      dataHtml += "<tr style=\"text-align: center;\">\n";
                      for (let key in columns) {
                          dataHtml += "<td>"+data[key]+"</td>\n";
                      }
                      dataHtml += "</tr>\n";
                  }
          
                  //完整html
                  let excelHtml = "<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n" +
                      "      xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n" +
                      "      xmlns=\"http://www.w3.org/TR/REC-html40\">\n" +
                      "<head>\n" +
                      "   <!-- 加這個,其他單元格帶邊框 -->" +
                      "   <xml>\n" +
                      "        <x:ExcelWorkbook>\n" +
                      "            <x:ExcelWorksheets>\n" +
                      "                <x:ExcelWorksheet>\n" +
                      "                    <x:Name></x:Name>\n" +
                      "                    <x:WorksheetOptions>\n" +
                      "                        <x:DisplayGridlines/>\n" +
                      "                    </x:WorksheetOptions>\n" +
                      "                </x:ExcelWorksheet>\n" +
                      "            </x:ExcelWorksheets>\n" +
                      "        </x:ExcelWorkbook>\n" +
                      "   </xml>\n" +
                      "   <style>td{font-family: \"宋體\";}</style>\n" +
                      "</head>\n" +
                      "<body>\n" +
                      "<table border=\"1\">\n" +
                      "    <thead>\n" +
                      columnHtml +
                      "    </thead>\n" +
                      "    <tbody>\n" +
                      dataHtml +
                      "    </tbody>\n" +
                      "</table>\n" +
                      "</body>\n" +
                      "</html>";
          
                  //下載
                  downloadByBlob((fileName || "導(dǎo)出Excel")+".xls",excelHtml);
              }

            效果演示

            導(dǎo)出txt文檔

          downloadByBlob("downloadByBlob-導(dǎo)出txt文檔.txt","downloadByBlob\n導(dǎo)出txt簡單測試\n");
          downloadByBase64("downloadByBase64-導(dǎo)出txt文檔.txt","downloadByBase64\n導(dǎo)出txt簡單測試\n");

            導(dǎo)出Excel表格

          exportExcel("xx業(yè)務(wù)Excel導(dǎo)出", {"id": "編號", "name": "名字", "age": "年齡", "time": "參加工作時間"}, [{
                      "id": "A001",
                      "name": "張三",
                      "age": "18",
                      "time": new Date().toLocaleString()
                  },{
                      "id": "A002",
                      "name": "李四",
                      "age": "20",
                      "time": new Date().toLocaleString()
                  }]);

            導(dǎo)出word文檔也是一樣

            后記

            參考上我們之前的《FreeMarker模板引擎》,先畫好我們想要的文檔格式然后轉(zhuǎn)成xml,調(diào)用我們封裝好的方法,將構(gòu)造好的xml內(nèi)容轉(zhuǎn)成文件,實現(xiàn)前端導(dǎo)出復(fù)雜格式文檔!

            如果有復(fù)雜數(shù)據(jù),建議還是在后端操作,當(dāng)然你也可以把數(shù)據(jù)返回前端在前端導(dǎo)出也行

            前端導(dǎo)出Excel主要是利用Bolb、base64,以及Excel支持html格式的特性,這個特性不僅前端可以利用,后端也一樣可以,這里也分享一下后端工具類,原理都是一樣的

          package cn.huanzi.qch.util;
          
          import javax.servlet.http.HttpServletResponse;
          import java.io.File;
          import java.io.OutputStream;
          import java.io.PrintWriter;
          import java.text.SimpleDateFormat;
          import java.util.*;
          
          /**
           * Excel工具類
           */
          public class ExcelUtil {
          
              /**
               * 導(dǎo)出
               * 無需依賴POI
               */
              /*
                  示例:
                  try {
                      //列名
                      LinkedHashMap<String, String> columns = new LinkedHashMap<>(4);
                      columns.put("id","編號");
                      columns.put("name","名字");
                      columns.put("age","年齡");
                      columns.put("time","參加工作時間");
          
                      //數(shù)據(jù)
                      List<Map<String, Object>> datas = new ArrayList<>(3);
                      HashMap<String, Object> hashMap = new HashMap<>();
                      hashMap.put("id","A001");
                      hashMap.put("name","張三");
                      hashMap.put("age",18);
                      hashMap.put("time",new Date());
                      datas.add(hashMap);
          
                      //帶換行符:
          
                      HashMap<String, Object> hashMap2 = new HashMap<>();
                      hashMap2.put("id","A002");
                      hashMap2.put("name","李四
          李四1
          李四2");
                      hashMap2.put("age",20);
                      hashMap2.put("time",new Date());
                      datas.add(hashMap2);
          
                      HashMap<String, Object> hashMap3 = new HashMap<>();
                      hashMap3.put("id","A003");
                      hashMap3.put("name","王五");
                      hashMap3.put("age",25);
                      hashMap3.put("time",new Date());
                      datas.add(hashMap3);
          
                      //導(dǎo)出
                      ExcelUtil.exportByResponse(this.getResponse(),"Excel導(dǎo)出測試",columns,datas);
                      //ExcelUtil.exportByFile(new File("D:\\XFT User\\Downloads\\Excel導(dǎo)出測試.xls"),columns,datas);
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
               */
              public static void exportByResponse(HttpServletResponse response, String fileName, LinkedHashMap<String, String> columns, List<Map<String, Object>> datas) throws Exception {
                  response.addHeader("Content-disposition", "attachment; filename=" + fileName + ".xls");
                  response.setContentType("application/ms-excel");
          
                  StringBuilder sb = exportOfData(columns, datas);
          
                  OutputStream out = response.getOutputStream();
                  out.write(sb.toString().getBytes("UTF-8"));
                  out.flush();
                  out.close();
              }
          
              public static void exportByFile(File file, LinkedHashMap<String, String> columns, List<Map<String, Object>> datas) {
                  StringBuilder sb = exportOfData(columns, datas);
          
                  try (PrintWriter myFile = new PrintWriter(file,"UTF-8")) {
                      myFile.println(sb);
                  } catch (Exception e) {
                      System.err.println("exportByFile(),操作出錯...");
                      e.printStackTrace();
                  }
                  System.out.println(file.getName() + ",操作完成!");
              }
          
              //其他單元格無邊框
              private static StringBuilder exportOfData(LinkedHashMap<String, String> columns, List<Map<String, Object>> datas) {
                  StringBuilder sb = new StringBuilder("<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"" +
                          "      xmlns:x=\"urn:schemas-microsoft-com:office:excel\"" +
                          "      xmlns=\"http://www.w3.org/TR/REC-html40\">");
          
                  //加這個,其他單元格帶邊框
                  sb.append("<head>" +
                          "    <xml>" +
                          "        <x:ExcelWorkbook>" +
                          "            <x:ExcelWorksheets>" +
                          "                <x:ExcelWorksheet>" +
                          "                    <x:Name></x:Name>" +
                          "                    <x:WorksheetOptions>" +
                          "                        <x:DisplayGridlines/>" +
                          "                    </x:WorksheetOptions>" +
                          "                </x:ExcelWorksheet>" +
                          "            </x:ExcelWorksheets>" +
                          "        </x:ExcelWorkbook>" +
                          "    </xml>" +
                          "   <style>td{font-family: \"宋體\";}</style>" +
                          "</head>");
          
                  sb.append("<body>");
          
                  sb.append("<table border=\"1\">");
          
                  //列名
                  sb.append("<tr style=\"text-align: center;\">");
                  for (Map.Entry<String, String> entry : columns.entrySet()) {
                      sb.append("<td style=\"background-color:#bad5fd\">" + entry.getValue() + "</td>");
                  }
                  sb.append("</tr>");
          
                  //數(shù)據(jù)
                  for (Map<String, Object> data : datas) {
                      sb.append("<tr style=\"text-align: center;\">");
                      for (Map.Entry<String, String> entry : columns.entrySet()) {
                          Object dataValue = data.get(entry.getKey());
          
                          //如果是日期類型
                          if (dataValue instanceof java.util.Date) {
                              dataValue = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(dataValue);
                          }
                          sb.append("<td>" + dataValue.toString() + "</td>");
                      }
                      sb.append("</tr>");
                  }
          
                  sb.append("</table>");
          
                  sb.append("</body>");
          
                  sb.append("</html>");
          
                  return sb;
              }
          
              //前端導(dǎo)出Excel
              /*
                  示例:
                   exportExcel("xx業(yè)務(wù)Excel導(dǎo)出", {"id": "編號", "name": "名字", "age": "年齡", "time": "參加工作時間"}, [{
                      "id": "A001",
                      "name": "張三",
                      "age": "18",
                      "time": new Date().toLocaleString()
                  },{
                      "id": "A002",
                      "name": "李四",
                      "age": "20",
                      "time": new Date().toLocaleString()
                  }]);
               */
              /*
                  //blob、base64轉(zhuǎn)文件下載,通過A標(biāo)簽?zāi)M點(diǎn)擊,設(shè)置文件名
                  //萬能流  application/octet-stream
                  //word文件  application/msword
                  //excel文件  application/vnd.ms-excel
                  //txt文件  text/plain
                  //圖片文件  image/png、jpeg、gif、bmp
                  function downloadByBlob(fileName, text) {
                      let a = document.createElement("a");
                      a.href = URL.createObjectURL(new Blob([text], {type: "application/octet-stream"}));
                      a.download = fileName || 'Blob導(dǎo)出測試.txt';
                      a.click();
                      a.remove();
                      URL.revokeObjectURL(a.href);
                  }
                  function downloadByBase64(fileName, text) {
                      let a = document.createElement('a');
                      a.href = 'data:application/octet-stream;base64,' + window.btoa(unescape(encodeURIComponent(text)));
                      a.download = fileName || 'Base64導(dǎo)出測試.txt';
                      a.click();
                      a.remove();
                      URL.revokeObjectURL(a.href);
                  }
              
                  //踹掉后端,前端導(dǎo)出Excel!
                  function exportExcel(fileName,columns,datas){
                      //列名
                      let columnHtml = "";
                      columnHtml += "<tr style=\"text-align: center;\">\n";
                      for (let key in columns) {
                          columnHtml += "<td style=\"background-color:#bad5fd\">"+columns[key]+"</td>\n";
                      }
                      columnHtml += "</tr>\n";
              
                      //數(shù)據(jù)
                      let dataHtml = "";
                      for (let data of datas) {
                          dataHtml += "<tr style=\"text-align: center;\">\n";
                          for (let key in columns) {
                              dataHtml += "<td>"+data[key]+"</td>\n";
                          }
                          dataHtml += "</tr>\n";
                      }
              
                      //完整html
                      let excelHtml = "<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n" +
                              "      xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n" +
                              "      xmlns=\"http://www.w3.org/TR/REC-html40\">\n" +
                              "<head>\n" +
                              "   <!-- 加這個,其他單元格帶邊框 -->" +
                              "   <xml>\n" +
                              "        <x:ExcelWorkbook>\n" +
                              "            <x:ExcelWorksheets>\n" +
                              "                <x:ExcelWorksheet>\n" +
                              "                    <x:Name></x:Name>\n" +
                              "                    <x:WorksheetOptions>\n" +
                              "                        <x:DisplayGridlines/>\n" +
                              "                    </x:WorksheetOptions>\n" +
                              "                </x:ExcelWorksheet>\n" +
                              "            </x:ExcelWorksheets>\n" +
                              "        </x:ExcelWorkbook>\n" +
                              "   </xml>\n" +
                              "   <style>td{font-family: \"宋體\";}</style>\n" +
                              "</head>\n" +
                              "<body>\n" +
                              "<table border=\"1\">\n" +
                              "    <thead>\n" +
                              columnHtml +
                              "    </thead>\n" +
                              "    <tbody>\n" +
                              dataHtml +
                              "    </tbody>\n" +
                              "</table>\n" +
                              "</body>\n" +
                              "</html>";
              
                      //下載
                      downloadByBlob((fileName || "導(dǎo)出Excel")+".xls",excelHtml);
                  }
               */
          }

          版權(quán)聲明

          作者:huanzi-qch

          出處:https://www.cnblogs.com/huanzi-qch

          若標(biāo)題中有“轉(zhuǎn)載”字樣,則本文版權(quán)歸原作者所有。若無轉(zhuǎn)載字樣,本文版權(quán)歸作者所有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,否則保留追究法律責(zé)任的權(quán)利.

          計模式三十六計之建造者模式(Builder)

          1. 設(shè)計意圖

          將復(fù)雜對象的構(gòu)造與其表示分離,以便相同的構(gòu)造過程可以創(chuàng)建不同的表示。

          2. 演示案例

          假設(shè)我們需要創(chuàng)建一個用戶對象,用戶對象的屬性有身份證號碼、姓名、年齡、性別、族別、地址。最簡單的方式是定義一個包含這六個屬性的構(gòu)造函數(shù)來完成對象的創(chuàng)建,但是,你想在構(gòu)建的過程中只想包含其中的一個或者幾個屬性的時候,問題來了,沒有與之對應(yīng)的構(gòu)造函數(shù)存在,也不可能提前定義多構(gòu)造函數(shù)來覆蓋這種動態(tài)傳參的構(gòu)造需求。這種類型的需求場景就需要建造者模式了(Builder)。

          簡而言之

          建造者模式的要領(lǐng)是允許你創(chuàng)建不同風(fēng)格的對象,同時避免構(gòu)造函數(shù)被污染。當(dāng)一個對象可能有N中風(fēng)格存在或者對象的創(chuàng)建要涉及到多個步驟的時候適用于建造者模式

          維基百科

          >構(gòu)建器模式是一種對象創(chuàng)建軟件設(shè)計模式,旨在尋找伸縮構(gòu)造器反模式的解決方案。

          在開始給出具體的代碼前,我們先對比一下常規(guī)的一種設(shè)計方式。就上述的案例場景,我們可能會給出如下的一個構(gòu)造函數(shù):

           public User(String id,String name,int age,int gender,String nation,String address){
          
           //setter...
          
          
          

          在這種設(shè)計方式下,當(dāng)用戶屬性改變時,構(gòu)造函數(shù)參數(shù)的數(shù)量可能會很快失去控制,并且很難理解構(gòu)造函數(shù)的參數(shù)排列,另外,如果用戶屬性繼續(xù)增加,構(gòu)造函數(shù)的參數(shù)列表將持續(xù)增長。這被稱為伸縮構(gòu)造反模式。

          3. 程序示例

          針對上述提到的問題,最合適的解決方案時使用建造者模式,首先我們需要創(chuàng)建一個User類:

          public class User {
           private String id; //身份證號碼
           private String name; //姓名
           private int age = 0; //年齡
           private int gender = 0;//0:保密,1:男性,2:女性
           private String nation; //族別
           private String address; //地址
          
           private User(Builder builder){
           this.id = builder.id;
           this.name = builder.name;
           this.age = builder.age;
           this.gender = builder.gender;
           this.nation = builder.nation;
           this.address = builder.address;
           }
           //getter...
           //setter...
           //toString...
          }
          
          

          然后我們需要創(chuàng)建一個Bulder類:

          public static class Builder{
           private String id; //身份證號碼
           private String name; //姓名
           private int age = 0; //年齡
           private int gender = 0;//0:保密,1:男性,2:女性
           private String nation = "none"; //族別
          
           private String address = "none"; //地址
           /**
           * 假定建造時必須提供身份證號碼和姓名
           **/
           public Builder(String id,String name){
           if(id == null || name == null){
           throw new IllegalArgumentException("id and name can not be null");
           }
           this.id = id;
           this.name = name;
           }
           public Builder withAge(int age){
           this.age = age;
           return this;
           }
           public Builder withGender(int gender){
           this.gender = gender;
           return this;
           }
           public Builder withNation(String nation){
           this.nation = nation;
           return this;
           }
           public Builder withAddress(String address){
           this.address = address;
           return this;
           }
           public User build(){
           return new User(this);
           }
          }
          
          

          說明:這里我們使用了一個靜態(tài)內(nèi)部類 **Builder** 來實現(xiàn)一個建造器

          最后我們可以這樣來創(chuàng)建一個用戶對象:

          public class TestUserBuilder{
           public static void main(String[] args){
          
           User zhangSan = new User.Builder("13579","張三").withAge(22).withGender(1).build();
           User wangWu = new User.Builder("24680","王五").withAge(30).withGender(1).withNation("漢族").build();
           User liLei = new User.Builder("123456","李蕾").withAge(18).withGender(2).withNation("苗族")
           .withAddress("貴州省黔西南布依族苗族自治州").build();
           System.out.println(zhangSan.toString());
           System.out.println(wangWu.toString());
           System.out.println(liLei.toString());
           }
          }
          
          

          輸入結(jié)果

          id:13579,name:張三,age:22,gender:1,nation:none,address:none
          id:24680,name:王五,age:30,gender:1,nation:漢族,address:none
          id:123456,name:李蕾,age:18,gender:2,name:苗族,address:貴州省黔西南布依族苗族自治州
          
          
          

          4.使用場景

          滿足一下需求的時候推薦使用建造者模式:

          1. 創(chuàng)建復(fù)雜對象的算法應(yīng)該獨(dú)立于組成對象的各個部分以及它們的組裝方式。

          2. 構(gòu)造過程必須允許對構(gòu)造的對象進(jìn)行不同的表示

          5.建造者模式應(yīng)用例子

          * [java.lang.StringBuilder](http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html)

          * [java.lang.StringBuffer](http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuffer.html#append-boolean-)

          6.總結(jié)

          建造者模式使得對象內(nèi)部的屬性可以獨(dú)立變化,使用者不必知道對象內(nèi)部的組成細(xì)節(jié),每個建造器相對獨(dú)立,與其他的建造器無關(guān)。建造者模式的應(yīng)用讓對象創(chuàng)建過程更加靈活和易于控制。建造者模式也有相應(yīng)的弊端,它使得對象的創(chuàng)建過程暴露給外界,讓整個對象的 **“加工工藝”** 變得不透明。

          ## 參考

          * [Effective Java (2nd Edition)](http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)


          主站蜘蛛池模板: 无码欧精品亚洲日韩一区夜夜嗨| 免费一本色道久久一区| 亚洲一区二区三区高清不卡| 精品一区精品二区| 日韩一区二区超清视频| 久久亚洲国产精品一区二区| 国产成人片视频一区二区| 亚洲国产欧美国产综合一区| 亚洲一区免费视频| 亚洲电影国产一区| 国产精品日本一区二区不卡视频 | 亚洲欧美日韩国产精品一区| 精品久久一区二区三区| 中文字幕一区二区三区在线播放| 在线精品日韩一区二区三区| 少妇一晚三次一区二区三区| 亚洲性无码一区二区三区| 色老头在线一区二区三区| 久久国产免费一区二区三区| 国产精品免费一区二区三区四区| 美女啪啪一区二区三区| 色窝窝无码一区二区三区色欲| 久久久久一区二区三区| 78成人精品电影在线播放日韩精品电影一区亚洲 | 国产乱码精品一区二区三区| 精品无码综合一区二区三区| 无码人妻精一区二区三区| 秋霞日韩一区二区三区在线观看 | 久久精品视频一区二区三区| 久久久久99人妻一区二区三区| 久久se精品一区二区国产| 人妻无码一区二区不卡无码av | 日本一区二区三区免费高清在线| 国产亚洲福利一区二区免费看| 天码av无码一区二区三区四区| 国产高清在线精品一区小说 | 亚洲一区二区三区在线网站| 色婷婷香蕉在线一区二区| 国产一国产一区秋霞在线观看| 精品一区二区无码AV| 人妻少妇精品视频一区二区三区|