.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字體支持等等。
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!
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);
}
*/
}
作者: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)
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。