前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >体验“超级无敌”的文件上传组件bootstrap fileinput

体验“超级无敌”的文件上传组件bootstrap fileinput

作者头像
hotqin888
发布2019-11-04 13:37:39
2.6K0
发布2019-11-04 13:37:39
举报
文章被收录于专栏:hotqin888的专栏hotqin888的专栏

网页开发最最重要最最基本的就是富文本编辑器和文件上传,开始我迷信百度的ueditor和webupload,结果总是别扭,看来不能迷信BAT啊。富文本用了froala,文件上传早点用bootstrap fileinput那多炫啊。

参考网上的文章,走了不少弯路。

其实就是喜欢https://plugins.krajee.com/file-krajee-explorer-demo

里面的第二个Advanced Usage 这种列表的样式,如下,好漂亮。

当文件上传成功后,可以预览,可以下载(显示下载按钮),简直不要太棒!!

弯路大家就不要再走了,开始我在git上下载的js啊,css啊,引入本地的jquery.js啊,引入本地的bootstrap的css和js啊,都互相不匹配,折腾了好久。

最简单的办法就是将上述demo网页另存下来,所有的js和css基本就有了,然后用chrome浏览器打开调试,找到Resource,找到页面源码,找到里面引入的js和css,原封不动的放到你的页面中去,就像下面这样:

代码语言:javascript
复制
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<link href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" rel="stylesheet">
<link href="/static/bootstrap-fileinput/assets/prod/all-krajee.min.css?ver=201903112143" rel="stylesheet">
<link href="/static/bootstrap-fileinput/assets/1d958cec/css/fileinput.css?ver=201909132002" rel="stylesheet">
<link href="/static/bootstrap-fileinput/assets/1d958cec/themes/explorer/theme.min.css?ver=201908311938" rel="stylesheet">
<link href="/static/bootstrap-fileinput/assets/fc69cbca/css/dropdown.min.css" rel="stylesheet">
<script src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js" async></script>
<script src="https://buttons.github.io/buttons.js" async></script>
<link rel="stylesheet" type="text/css" href="/static/font-awesome-4.7.0/css/font-awesome.min.css"/>

<script id="dsq-count-scr" src="//krajee.disqus.com/count.js" async></script>
<script src="/static/bootstrap-fileinput/assets/1d958cec/js/plugins/purify.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script src="/static/bootstrap-fileinput/assets/prod/all-krajee.min.js?ver=201903112143"></script>
<script src="/static/bootstrap-fileinput/assets/1d958cec/js/plugins/sortable.min.js"></script>
<script src="/static/bootstrap-fileinput/assets/1d958cec/js/plugins/piexif.min.js"></script>
<script src="/static/bootstrap-fileinput/assets/1d958cec/js/fileinput.js?ver=201909132002"></script>
<script src="/static/bootstrap-fileinput/assets/1d958cec/themes/explorer/theme.min.js?ver=201908311938"></script>
<script src="/static/bootstrap-fileinput/assets/fc69cbca/js/dropdown.min.js"></script>

能够存到本地的,就用本地的css和js,这些本地的js和css,一定要用刚才网页另存下来的里面的css和js,或者在chrome调试里Network下将js和css另存下来也可以。

这样就可以上传啊,预览(如下)啊,效果特别好。

前端完整代码:

代码语言:javascript
复制
<!DOCTYPE html>
<!-- KRAJEE EXPLORER THEME (ADVANCED) -->
<title>规范对标</title>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<link href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" rel="stylesheet">
<link href="/static/bootstrap-fileinput/assets/prod/all-krajee.min.css?ver=201903112143" rel="stylesheet">
<link href="/static/bootstrap-fileinput/assets/1d958cec/css/fileinput.css?ver=201909132002" rel="stylesheet">
<link href="/static/bootstrap-fileinput/assets/1d958cec/themes/explorer/theme.min.css?ver=201908311938" rel="stylesheet">
<link href="/static/bootstrap-fileinput/assets/fc69cbca/css/dropdown.min.css" rel="stylesheet">
<script src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js" async></script>
<script src="https://buttons.github.io/buttons.js" async></script>
<link rel="stylesheet" type="text/css" href="/static/font-awesome-4.7.0/css/font-awesome.min.css"/>

<script id="dsq-count-scr" src="//krajee.disqus.com/count.js" async></script>
<script src="/static/bootstrap-fileinput/assets/1d958cec/js/plugins/purify.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script src="/static/bootstrap-fileinput/assets/prod/all-krajee.min.js?ver=201903112143"></script>
<script src="/static/bootstrap-fileinput/assets/1d958cec/js/plugins/sortable.min.js"></script>
<script src="/static/bootstrap-fileinput/assets/1d958cec/js/plugins/piexif.min.js"></script>
<script src="/static/bootstrap-fileinput/assets/1d958cec/js/fileinput.js?ver=201909132002"></script>
<script src="/static/bootstrap-fileinput/assets/1d958cec/themes/explorer/theme.min.js?ver=201908311938"></script>
<script src="/static/bootstrap-fileinput/assets/fc69cbca/js/dropdown.min.js"></script>

<!-- ************ -->

<!-- <link href="/static/bootstrap-fileinput/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous"> -->
<!-- <link href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" rel="stylesheet"> -->
<!-- <link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css"/> -->

<!-- <link href="/static/bootstrap-fileinput/css/fileinput.min.css" rel="stylesheet"> -->
<!-- <link href="/static/bootstrap-fileinput/themes/explorer/theme.css" rel="stylesheet"> -->

<!-- <script src="/static/bootstrap-fileinput/js/jquery-3.1.1.min.js" crossorigin="anonymous"></script> -->
<!-- <script src="/static/bootstrap-fileinput/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script> -->

<!-- <script src="/static/bootstrap-fileinput/js/fileinput.js"></script> -->
<!-- <script src="/static/bootstrap-fileinput/themes/explorer/theme.js"></script> -->
<!-- <script src="/static/bootstrap-fileinput/js/plugins/piexif.js" type="text/javascript"></script> -->
<!-- <script src="/static/bootstrap-fileinput/js/plugins/sortable.js" type="text/javascript"></script> -->
<!-- <script src="/static/bootstrap-fileinput/js/locales/zh.js" type="text/javascript"></script> -->


<div class="file-loading">
    <input id="input-ke-2" name="input-ke-2[]" type="file" multiple data-browse-on-zone-click="true">
    <!-- <input id="input-b1" name="input-b1" type="file" class="file" > -->
</div>
<script>
<!-- must load the font-awesome.css for this example -->

	$("#input-ke-2").fileinput({
    language:'zh',
    theme: "explorer",
    uploadAsync: false,//同步上传
    uploadUrl: "/v1/fileinput/bootstrapfileinput",
    minFileCount: 1,
    maxFileCount: 5,
    maxFileSize: 10000,
    removeFromPreviewOnError: true,
    overwriteInitial: false,
    previewFileIcon: '<i class="fas fa-file"></i>',
    initialPreview: [
      // IMAGE DATA
      // 'https://picsum.photos/800/560?image=1071',
      // IMAGE RAW MARKUP
      // '<img src="https://picsum.photos/800/560?image=1075" class="kv-preview-data file-preview-image">',
      // TEXT DATA
      // "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ut mauris ut libero fermentum feugiat eu et dui. Mauris condimentum rhoncus enim, sed semper neque vestibulum id. Nulla semper, turpis ut consequat imperdiet, enim turpis aliquet orci, eget venenatis elit sapien non ante. Aliquam neque ipsum, rhoncus id ipsum et, volutpat tincidunt augue. Maecenas dolor libero, gravida nec est at, commodo tempor massa. Sed id feugiat massa. Pellentesque at est eu ante aliquam viverra ac sed est.",
      // PDF DATA
      // 'http://kartik-v.github.io/bootstrap-fileinput-samples/samples/pdf-sample.pdf',
      // VIDEO DATA
      // "http://kartik-v.github.io/bootstrap-fileinput-samples/samples/small.mp4"
    ],
    initialPreviewAsData: true, // defaults markup  
    initialPreviewConfig: [
      // {caption: "Image 11.jpg", size: 762980, url: "/site/file-delete", downloadUrl: 'https://picsum.photos/800/460?image=11', key: 11},
      // {previewAsData: false, size: 823782, caption: "Image 13.jpg", url: "/site/file-delete", downloadUrl: 'https://picsum.photos/800/460?image=13', key: 13}, 
      // {caption: "Lorem Ipsum.txt", type: "text", size: 1430, url: "/site/file-delete", key: 12}, 
      // {type: "pdf", size: 8000, caption: "PDF Sample.pdf", url: "/site/file-delete", key: 14}, 
      // {type: "video", size: 375000, filetype: "video/mp4", caption: "Krajee Sample.mp4", url: "/site/file-delete", key: 15} 
    ],
    // initialPreviewDownloadUrl:'https://picsum.photos/1920/1080?image={key}', // the key will be dynamically replaced 
    uploadExtraData: {
      img_key: "1000",
      img_keywords: "happy, nature"
    },
    preferIconicPreview: true, // this will force thumbnails to display icons for following file extensions
       previewFileIconSettings: { // configure your icon file extensions
      'doc': '<i class="fas fa-file-word text-primary"></i>',
      'xls': '<i class="fas fa-file-excel text-success"></i>',
      'ppt': '<i class="fas fa-file-powerpoint text-danger"></i>',
      'pdf': '<i class="fas fa-file-pdf text-danger"></i>',
      'zip': '<i class="fas fa-file-archive text-muted"></i>',
      'htm': '<i class="fas fa-file-code text-info"></i>',
      'txt': '<i class="fas fa-file-text text-info"></i>',
      'mov': '<i class="fas fa-file-video text-warning"></i>',
      'mp3': '<i class="fas fa-file-audio text-warning"></i>',
      // note for these file types below no extension determination logic 
      // has been configured (the keys itself will be used as extensions)
      'jpg': '<i class="fas fa-file-image text-danger"></i>', 
      'gif': '<i class="fas fa-file-image text-muted"></i>', 
      'png': '<i class="fas fa-file-image text-primary"></i>'    
    },
    previewFileExtSettings: { // configure the logic for determining icon file extensions
      'doc': function(ext) {
        return ext.match(/(doc|docx)$/i);
      },
      'xls': function(ext) {
        return ext.match(/(xls|xlsx)$/i);
      },
      'ppt': function(ext) {
        return ext.match(/(ppt|pptx)$/i);
      },
      'zip': function(ext) {
        return ext.match(/(zip|rar|tar|gzip|gz|7z)$/i);
      },
      'htm': function(ext) {
        return ext.match(/(htm|html)$/i);
      },
      'txt': function(ext) {
        return ext.match(/(txt|ini|csv|java|php|js|css)$/i);
      },
      'mov': function(ext) {
        return ext.match(/(avi|mpg|mkv|mov|mp4|3gp|webm|wmv)$/i);
      },
      'mp3': function(ext) {
        return ext.match(/(mp3|wav)$/i);
      }
    }
	}).on("filebatchselected", function (event, data) {//选择即上传
    if (data.length == 0) {
      return;
    }
  });

  // 上传成功回调
  $("#input-ke-2").on("filebatchuploadcomplete", function() {
    alert("上传附件成功");
    // setTimeout("closeUpladLayer()",2000)
  });
  // 上传失败回调
  $('#input-ke-2').on('fileerror', function(event, data, msg) {
    alert(data.msg);
    // tokenTimeOut(data);
  });
</script>

</html> 

服务的golang:

代码语言:javascript
复制
type Fileinput struct {
	InitialPreview       []string        `json:"initialPreview"`
	InitialPreviewConfig []PreviewConfig `json:"initialPreviewConfig"`
	// InitialPreviewDownloadUrl []string        `json:"initialPreviewDownloadUrl"`
}

// type Preview struct {
// 	Url  string
// }

type PreviewConfig struct {
	Caption     string `json:"caption"`
	Size        int64  `json:"size"`
	Url         string `json:"url"`
	DownloadUrl string `json:"downloadUrl"`
	Key         string `json:"key"`
}

// @Title post bootstrapfileinput
// @Description post file by BootstrapFileInput
// @Success 200 {object} SUCCESS
// @Failure 400 Invalid page supplied
// @Failure 404 articl not found
// @router /bootstrapfileinput [post]
//独立上传文件模式
func (c *FileinputController) BootstrapFileInput() {
	//获取上传的文件
	_, h, err := c.GetFile("input-ke-2[]")
	if err != nil {
		beego.Error(err)
	}
	fileSuffix := path.Ext(h.Filename)
	// random_name
	newname := strconv.FormatInt(time.Now().UnixNano(), 10) + fileSuffix // + "_" + filename
	year, month, _ := time.Now().Date()
	err = os.MkdirAll("./attachment/legislation/"+strconv.Itoa(year)+month.String()+"/", 0777) //..代表本当前exe文件目录的上级,.表示当前目录,没有.表示盘的根目录
	if err != nil {
		beego.Error(err)
	}
	var filesize int64

	if h != nil {
		//保存附件
		filepath := "./attachment/legislation/" + strconv.Itoa(year) + month.String() + "/" + newname
		Url := "/attachment/legislation/" + strconv.Itoa(year) + month.String() + "/"
		err = c.SaveToFile("input-ke-2[]", filepath) //.Join("attachment", attachment)) //存文件    WaterMark(path)    //给文件加水印
		if err != nil {
			beego.Error(err)
		}
		filesize, _ = FileSize(filepath)
		filesize = filesize / 1000.0

		// 解析excel
		if fileSuffix == ".XLSX" || fileSuffix == ".xlsx" || fileSuffix == ".XLS" || fileSuffix == ".xls" {
			// xlsx, err := excelize.OpenFile(filepath)
			xlsx, err := xlsx.OpenFile(filepath)
			if err != nil {
				beego.Error(err)
				return
			}
			for _, sheet := range xlsx.Sheets {
				for i, row := range sheet.Rows {
					if i != 0 {
						// 这里要判断单元格列数,如果超过单元格使用范围的列数,则出错for j := 2; j < 7; j += 5 {
						j := 1
						standardtitle := row.Cells[j].String()
						if err != nil {
							beego.Error(err)
						}
						//2、根据名称搜索标准版本库,取得名称和版本号
						library, err := models.SearchLiabraryName(standardtitle)
						// beego.Info(library)
						if err != nil {
							beego.Error(err)
						}
						var LibraryNumber string
						if len(library) != 0 { //library != nil这样不行,空数组不是nil
							// beego.Info(library)
							//3、构造struct
							for j, w := range library {
								// beego.Info(w)
								if j == 0 {
									LibraryNumber = w.Category + " " + w.Number + "-" + w.Year //规范有效版本库中的完整编号
								} else {
									LibraryNumber = LibraryNumber + "," + w.Category + " " + w.Number + "-" + w.Year //规范有效版本库中的完整编号
								}
							}
							row.Cells[j+1].Value = LibraryNumber
						}

					}
				}
			}
			err = xlsx.Save(filepath)
			if err != nil {
				beego.Error(err)
			}
			// for index, name := range xlsx.GetSheetMap() {
			// 	fmt.Println(index, name)
			// 	// Get all the rows in the Sheet1.
			// 	rows, err := xlsx.GetRows(name)
			// 	for _, row := range rows {
			// 		for _, colCell := range row {
			// 			fmt.Print(colCell, "\t")
			// 		}
			// 		fmt.Println()
			// 	}
			// }
		}
		var fileinput Fileinput
		fileinput.InitialPreview = []string{Url + newname}
		// fileinput.InitialPreviewDownloadUrl = []string{Url + newname}
		// var config PreviewConfig
		config := make([]PreviewConfig, 1)
		config[0].Caption = newname
		config[0].DownloadUrl = Url + newname
		config[0].Size = filesize
		config[0].Key = Url + newname
		config[0].Url = Url + newname
		fileinput.InitialPreviewConfig = config
		c.Data["json"] = fileinput
		c.ServeJSON()
	} else {
		c.Data["json"] = map[string]interface{}{"state": "ERROR", "link": "", "title": "", "original": ""}
		c.ServeJSON()
	}
}

注意:服务的用前端里的name值来得到上传的文件。

代码语言:javascript
复制
<input id="input-ke-2" name="input-ke-2[]" type="file" multiple data-browse-on-zone-click="true">

服务的的返回值,必须包含InitialPreview和InitialPreviewConfig,结构体如下:

代码语言:javascript
复制
type Fileinput struct {
	InitialPreview       []string        `json:"initialPreview"`
	InitialPreviewConfig []PreviewConfig `json:"initialPreviewConfig"`
	// InitialPreviewDownloadUrl []string        `json:"initialPreviewDownloadUrl"`
}

type PreviewConfig struct {
	Caption     string `json:"caption"`
	Size        int64  `json:"size"`
	Url         string `json:"url"`
	DownloadUrl string `json:"downloadUrl"`
	Key         string `json:"key"`
}

当InitialPreviewConfig中包含了downloadUrl时,前端收到这个json文件,就会自动显示下载按钮了。

返回值如下:

代码语言:javascript
复制
{initialPreview: ["/attachment/legislation/2019November/1572777975188444800.xlsx"],…}
initialPreview: ["/attachment/legislation/2019November/1572777975188444800.xlsx"]
0: "/attachment/legislation/2019November/1572777975188444800.xlsx"
initialPreviewConfig: [{caption: "1572777975188444800.xlsx", size: 11,…}]
0: {caption: "1572777975188444800.xlsx", size: 11,…}
caption: "1572777975188444800.xlsx"
downloadUrl: "/attachment/legislation/2019November/1572777975188444800.xlsx"
key: "/attachment/legislation/2019November/1572777975188444800.xlsx"
size: 11
url: "/attachment/legislation/2019November/1572777975188444800.xlsx"

我这个是为了写一个规范对标的服务,当用户上传excel文件后,服务端收到excel,进行解析,将excel第二列的所有规范名称循环,从数据库中查询出这个规范名称对应的规范号,填入第三列中,完成后提供给用户下载。注意:这个操作要用同步上传模式,不能用异步上传模式,因为要等待服务端处理完成文件,才能显示下载按钮。

下一步提供word文件解析……

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-11-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档