在SharePoint 2010文档库中,结合单选框,在Ribbon中提供了批量处理文档的功能,比如,批量删除、批量签出、批量签入等,但是,很遗憾,没有提供批量下载,如图:
若选中多个文档后,会发现Download a Copy这个Ribbon按钮变灰了,这几天,我自己做了一个Ribbon,实现了批量下载的功能,向大家介绍一下。
先来说一下我这个批量下载的原理:
1. Ribbon按钮。在前端有一个Ribbon按钮,我也把它安置在Copies这个group里,它的作用是取得当前的文档库ID和所有被选中的条目的ID,作为参数传给下载页,下载页是一个Application Page。
2. 获取文档库中的文档。在下载页完成,根据传递来的文档库ID和item ID, 获得对应的SPDocumentLibrary和SPFile。
3. 把存放在数据库中的文档转化为实际的文档。在下载页完成,由于文档库中的文档是以二进制存放在数据库中,因此需要转化为实际的文档,为了打包方便,在服务器创建一个单独的文件夹存放,我以文档库的名字+当前的时间来作为文件夹的名称。
4. 打包下载。在下载页完成,将对应的文件夹打包成.zip包,完成下载。
要用到的技术:
1. 自定义Ribbon。请参阅我的另一篇随笔:SharePoint 2010自定义开发Ribbon。
2. Application Page。不再赘述。
3. 压缩。我使用的开源的ICSharpCode.SharpZIPLib。
开发工具还是使用Visual Studio 2010:
通过Visual Studio 2010,可以非常方便的开发自定义Ribbon和Application Page。
分别介绍一下:
1. Ribbon。
主要来看一下这个Ribbon按钮的Command Action:
1
var
ids
=
''
,url
=
''
;
2
var
c
=
ctx.dictSel;
3
for
(
var
key
in
c)
4
{
5
ids
=
ids
+
c[key].id
+
'
,
'
;
6
};
7
if
(ids
!=
''
)
8
{
9
url
=
ctx.HttpRoot
+
'
/_layouts/downloads/download.aspx?listid=
'
+
ctx.listName
+
'
;
'
+
ids;
10
window.open(url);
11
}
12
其中,ctx为current context,类似于我们在后台使用SPContext,在SharePoint 2010页面中都会有这个context,它是一个ContextInfo对象,在一个页面的源文件中,可以看到
<
script type
=
"
text/javascript
"
>
ctx
=
new
ContextInfo();
var
existingHash
=
''
;
if
(window.location.href.indexOf(
"
#
"
)
>
-
1
)
{ existingHash
=
window.location.href.substr(window.location.href.indexOf(
"
#
"
));
}
ctx.existingServerFilterHash
=
existingHash;
if
(ctx.existingServerFilterHash.indexOf(
"
ServerFilter=
"
)
==
1
)
{ ctx.existingServerFilterHash
=
ctx.existingServerFilterHash.replace(
/
-
/
g,
'
&
'
).replace(
/
&&
/
g,
'
-
'
);
var
serverFilterRootFolder
=
GetUrlKeyValue(
"
RootFolder
"
,
true
,ctx.existingServerFilterHash);
var
currentRootFolder
=
GetUrlKeyValue(
"
RootFolder
"
,
true
);
if
(
""
==
serverFilterRootFolder
&&
""
!=
currentRootFolder)
{ ctx.existingServerFilterHash
+=
"
&RootFolder=
"
+
currentRootFolder; } window.location.hash
=
''
; window.location.search
=
'
?
'
+
ctx.existingServerFilterHash.substr(
"
ServerFilter=
"
.length
+
1
); }
ctx.listBaseType
=
1
;
ctx.NavigateForFormsPages
=
false
;
ctx.listTemplate
=
"
101
"
;
ctx.listName
=
"
{E1616EE0-C898-435C-BFA8-CBC1C5D86B67}
"
;
ctx.view
=
"
{FCBEAC6C-FAC6-4951-A06B-9561E7C8E8EC}
"
;
ctx.listUrlDir
=
"
/Shared%20Documents
"
;
ctx.HttpPath
=
"
http://TestSite:8080/_vti_bin/owssvr.dll?CS=65001
"
;
ctx.HttpRoot
=
"
http://TestSite:8080
"
;
ctx.imagesPath
=
"
/_layouts/images/
"
; ctx.PortalUrl
=
""
; ctx.SendToLocationName
=
""
; ctx.SendToLocationUrl
=
""
; ctx.RecycleBinEnabled
=
1
; ctx.OfficialFileName
=
""
; ctx.OfficialFileNames
=
""
; ctx.WriteSecurity
=
"
1
"
; ctx.SiteTitle
=
"
KevinTest
"
; ctx.ListTitle
=
"
Shared Documents
"
;
if
(ctx.PortalUrl
==
""
) ctx.PortalUrl
=
null
; ctx.displayFormUrl
=
"
http://TestSite:8080/_layouts/listform.aspx?PageType=4&ListId={E1616EE0-C898-435C-BFA8-CBC1C5D86B67}
"
; ctx.editFormUrl
=
"
http://TestSite:8080/_layouts/listform.aspx?PageType=6&ListId={E1616EE0-C898-435C-BFA8-CBC1C5D86B67}
"
; ctx.isWebEditorPreview
=
0
; ctx.ctxId
=
59
; ctx.isXslView
=
true
;
if
(g_ViewIdToViewCounterMap[
"
{FCBEAC6C-FAC6-4951-A06B-9561E7C8E8EC}
"
]
==
null
) g_ViewIdToViewCounterMap[
"
{FCBEAC6C-FAC6-4951-A06B-9561E7C8E8EC}
"
]
=
59
; ctx.CurrentUserId
=
1
; ctx.ContentTypesEnabled
=
true
; ctx59
=
ctx; g_ctxDict[
'
ctx59
'
]
=
ctx;
<
/
script>
2. 下载页。
很好理解,直接看代码吧。
1
using System;
2
using Microsoft.SharePoint;
3
using Microsoft.SharePoint.WebControls;
4
using System.Web;
5
using System.IO;
6
using System.Diagnostics;
7
8
using ICSharpCode.SharpZipLib.Zip;
9
using ICSharpCode.SharpZipLib.Core;
10
11
12
namespace ProjectFor8080.Layouts.Downloads
13
{
14
public partial class Download : LayoutsPageBase
15
{
16
protected
void
Page_Load(object sender, EventArgs e)
17
{
18
if
(
!
string.IsNullOrEmpty(Request.Params[
"
listid
"
]))
19
{
20
SPContext context
=
SPContext.Current;
21
22
SPWeb web
=
context.Web;
23
24
string folder
=
@
"
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\template\LAYOUTS\Downloads\Files\
"
;
25
26
string listid
=
Request.Params[
"
listid
"
];
27
string[] downloadParams
=
listid.Split(
'
;
'
);
28
string[] fileIds
=
downloadParams[
1
].Split(
'
,
'
);
29
30
Guid listGuid
=
new
Guid(downloadParams[
0
]);
31
32
SPDocumentLibrary sdl
=
web.Lists[listGuid] as SPDocumentLibrary;
33
34
//
create the files folder under Downloads\Files
35
string time
=
DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss_fff");
36
37
string folderPath
=
folder
+
sdl.Title
+
time;
38
39
Directory.CreateDirectory(folderPath);
40
41
//
download the files from library
42
for
(
int
i
=
0
;i
<
fileIds.Length
-
1
;i
++
)
43
{
44
SPFile file
=
sdl.GetItemById(Int32.Parse(fileIds[i])).File;
45
string path
=
folderPath
+
@
"
\
"
+
file.Name;
46
FileStream fs
=
new
FileStream(path, FileMode.OpenOrCreate);
47
byte
[] fileByte
=
file.OpenBinary();
48
fs.Write(fileByte,
0
, fileByte.Length);
49
fs.Flush();
50
fs.Close();
51
52
}
53
54
//
zip file
55
56
string zipName
=
sdl.Title
+
time
+
"
.zip
"
;
57
string zipPath
=
folder
+
zipName;
58
CreateZipFile(folderPath, zipPath);
59
string downloadUrl
=
context.Site.Url
+
@
"
/_layouts/downloads/files/
"
+
zipName;
60
61
Response.Redirect(downloadUrl);
62
}
63
else
64
return
;
65
}
66
private static
void
CreateZipFile(string filesPath, string zipFilePath)
67
{
68
try
69
{
70
string[] filenames
=
Directory.GetFiles(filesPath);
71
72
using (ZipOutputStream s
=
new
ZipOutputStream(File.Create(zipFilePath)))
73
{
74
s.SetLevel(
9
);
//
压缩级别 0-9
75
76
//
s.Password = "123"; //Zip压缩文件密码
77
78
byte
[] buffer
=
new
byte
[
4096
];
//
缓冲区大小
79
80
foreach (string file
in
filenames)
81
{
82
ZipEntry entry
=
new
ZipEntry(Path.GetFileName(file));
83
84
entry.DateTime
=
DateTime.Now;
85
86
s.PutNextEntry(entry);
87
88
using (FileStream fs
=
File.OpenRead(file))
89
{
90
int
sourceBytes;
91
do
92
{
93
sourceBytes
=
fs.Read(buffer,
0
, buffer.Length);
94
s.Write(buffer,
0
, sourceBytes);
95
}
while
(sourceBytes
>
0
);
96
}
97
}
98
s.Finish();
99
s.Close();
100
}
101
}
102
catch
(Exception ex)
103
{
104
HttpContext.Current.Response.Write(ex.Message);
105
}
106
}
107
}
108
}
109
运行效果:
选中文档,点击“Multiple Downloads”后,直接弹出IE的下载对话框: