项目介绍
本项目借鉴了雀语的一些UI设计,实现了文档在线管理的功能,知识库可以对不同分类的文档建立不同的库,知识库里面左边可以维护菜单菜单目录,右边实现在线预览。该项目可以防止用户下载和复制文档,只支持在线预览。
技术实现
文档上传的时候通过aspose把图片word和execel类型的文件转为pdf文件存储到nas,前端预览使用pdf.js加载预览pdf文档
项目预览
开发介绍
目录维护
左侧菜单点击加号可以维护目录
前端代码
<body class="white-bg">
<div class="ibox-content">
<form class="form-horizontal m-t" id="form1">
<input id="id" name="id" type="hidden" />
<input id="parentid" name="parentid" type="hidden" />
<input id="deletemark" name="deletemark" type="hidden" />
<input id="createdate" name="createdate" type="hidden" />
<input id="createuserId" name="createuserId" type="hidden" />
<input id="createusername" name="createusername" type="hidden" />
<input id="modifydate" name="modifydate" type="hidden" />
<input id="modifyuserid" name="modifyuserid" type="hidden" />
<input id="modifyusername" name="modifyusername" type="hidden" />
<div class="row">
<div class="col-xs-12">
<input type="text" id="name" class="form-control" placeholder="名称" />
</div>
<div class="col-xs-12">
<textarea id="remark" class="form-control" placeholder="描述" style="width:100%;height:100px;"></textarea>
</div>
<div class="col-xs-12">
<input type="text" id="sortcode" class="form-control" placeholder="序号" />
</div>
<div class="col-xs-12">
<textarea id="keywords" class="form-control" placeholder="关键词" style="width:100%;height:100px;"></textarea>
</div>
</div>
</form>
</div>
</body>
后端代码
@ApiOperation(value = "保存", notes = "")
@PostMapping(value="/Save")
public Result Save(@RequestBody String json) {
DocmMenu model = (DocmMenu) JSON.parseObject(json, DocmMenu.class);
if(StrUtils.isBlank(model.getId())){
model.setCreateuserid("admin");
model.setDeletemark(new BigDecimal(0));
model.setCreateusername("admin");
model.setCreatedate(DateUtils.getNow());
model.setId(UUID.randomUUID().toString());
docmMenuService.add(model);
}else {
docmMenuService.update(model);
}
return Result.success(model,"成功!");
}
文档维护
文档维护使用Dropzone实现前端文件上传,支持历史版本管理。
前端代码
<!DOCTYPE html>
<html>
<head>
<title>文档管理</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="favicon.ico">
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/font-awesome.min.css" rel="stylesheet">
<link href="../css/plugins/jsTree/style.min.css" rel="stylesheet">
<link href="../css/plugins/bootstrap-table/bootstrap-table.min.css" rel="stylesheet">
<link href="../css/plugins/dropzone/dropzone.css" rel="stylesheet" type="text/css" />
<!-- 全局js -->
<script src="../js/jquery.min.js"></script>
<script src="../js/bootstrap.min.js"></script>
<script src="../js/plugins/jsTree/jstree.min.js"></script>
<script src="../js/plugins/bootstrap-table/bootstrap-table.min.js"></script>
<script src="../js/plugins/layer/layer.min.js"></script>
<script src="../js/plugins/dropzone/dropzone.js"></script>
<script src="../js/bd-framework.js"></script>
</head>
<body class="white-bg">
<div>
<table id="table" style="width:100%"></table>
<div id="main-container" style="margin-top: 10px;">
<form action="/" class="dropzone" enctype="multipart/form-data" id="my-dropzone"
method="post">
</form>
<textarea id="remark" class="form-control" placeholder="上传备注" style="width:100%;height:100px;"></textarea>
<div>
<!--上传按钮,提供多张图片一次性上传的功能-->
<button id="submit-all" class="btn btn-outline btn-default" type="submit" >上传</button>
</div>
</div>
</div>
<script>
var $table = $('#table');
$(function () {
getFileList();
})
function getFileList() {
$table.html("");
$.get("/api/Attachment/getList?businessid="+GetQuery('businessid'), {}, function (result, resultState) {
if (result.code == 200) {
if (result.data.length > 0) {
$table.append('<tr style="text-align: center; vertical-align: middle; border-style:solid; border-width:1px; ">'
+ '<td style="border-style:solid; border-width:1px;"><div style="padding:10px;width:30px;">序号</div></td>'
+ '<td style="border-style:solid; border-width:1px;"><div style="padding:10px;width:100px;">文件名称</div></td>'
+ '<td style="border-style:solid; border-width:1px;"><div style="padding:10px;width:80px;">上传人员</div></td>'
+ '<td style="border-style:solid; border-width:1px;"><div style="padding:10px;width:100px;">上传日期</div></td>'
+ '<td style="border-style:solid; border-width:1px;"><div style="padding:10px;width:200px;">备注</div></td>'
+ '<td style="border-style:solid; border-width:1px;"><div style="padding:10px;width:50px;">操作</div></td>'
+ '</tr>'
);
for (var i = 0; i < result.data.length; i++) {
if (result.data[i].EXTENSION != "pdf" || (result.data[i].TMP_BUSINESSID || '') =='') {
$table.append('<tr style="border-style:solid; border-width:1px;">'
+ '<td style="border-style:solid; border-width:1px;text-align:center;">' + (i + 1) + '</td>'
+ '<td style="border-style:solid; border-width:1px;">'
+ '<a onclick="Download(\'' + result.data[i].ID + '\')" style="float: left" href="javascript:void(0)"><u>' + result.data[i].NAME + '</u></a>'
+ '</td>'
+ '<td style="border-style:solid; border-width:1px;">' + result.data[i].CREATEUSERNAME + '</td>'
+ '<td style="border-style:solid; border-width:1px;">' + result.data[i].CREATETIME + '</td>'
+ '<td style="border-style:solid; border-width:1px;">' + (result.data[i].REMARK || '') + '</td>'
+ '<td style="border-style:solid; border-width:1px;">'
+ '<div style="position:relative;padding:10px;">'
+ '<button type="button" onclick="FileDelete(\'' + result.data[i].ID + '\')" data-id="' + result.data[i].ID + '">'
+ '删除'
+ '</button>'
+ '</div>'
+ '</td>'
+ '</tr>'
);
}
}
}
}
})
}
function FileDelete(Id) {
var index = parent.layer.confirm('是否删除?', {
btn: ['是', '否'] //按钮
}, function () {
$.get("/api/Attachment/deleteByPDF", { id: Id }, function (result, resultState) {
if (result.code == 200) {
parent.layer.msg("删除成功!");
getFileList();
} else {
parent.layer.msg(result.message);
getFileList();
}
}, "json");
parent.layer.close(index);
}, function () {
parent.layer.close(index);
});
}
function Download(Id) {
window.open('/api/Attachment/downFile?id=' + Id);
};
</script>
<script>
var loadIndex = null;
//Dropzone的初始化,myDropzone为form的id
Dropzone.options.myDropzone = {
params: {
businessid: GetQuery('businessid'),
filePath: 'DocM'
// 您可以在这里添加其他参数
},
//指定上传的路径
url: "/api/Attachment/uploadFilesToPDF",
maxFiles: 1, // 用于限制此Dropzone将处理的最大文件数
maxFilesize: 100, // MB
acceptedFiles: ".doc,.docx,.pdf,.PDF,.jpg,.JPG,.gif,.GIF,.png,.PNG,.bmp,.BMP", // 上传的类型
dictDefaultMessage:
'<div style="text-align: center; vertical-align: middle;padding-top:38px;"><span>将文件拖拽到此处</span> \
<span>(或点击上传)</span></div>'
,
dictResponseError: 'Error while uploading file!',
dictFileTooBig: "最大100M",
//添加上传取消和删除预览的链接,默认不添加
addRemoveLinks: true,
//关闭自动上传功能,默认会true会自动上传
//也就是添加一张图片向服务器发送一次请求
autoProcessQueue: false,
//允许上传多个
uploadMultiple: false,
//记得修改web.config 限制上传文件大小的节
parallelUploads: 100,
init: function () {
var submitButton = document.querySelector("#submit-all")
myDropzone = this; // closure
//为上传按钮添加点击事件
submitButton.addEventListener("click", function () {
Dropzone.options.myDropzone.params.remark = $("#remark").val();
loadIndex = parent.layer.load();
//手动上传所有文件
myDropzone.processQueue();
});
//当添加图片后的事件,上传按钮恢复可用
this.on("addedfile", function () {
$("#submit-all").removeAttr("disabled");
});
//当上传完成后的事件,接受的数据为JSON格式
this.on("complete", function (data) {
parent.layer.close(loadIndex);
if (this.getUploadingFiles().length === 0 && this.getQueuedFiles().length === 0) {
var res = eval('(' + data.xhr.responseText + ')');
var msg;
if (res.code == 200) {
msg = "已成功上传!";
this.removeAllFiles();
getFileList()
}
else {
msg = "上传失败,失败的原因是:" + res.Message;
}
parent.layer.msg(msg);
}
});
//删除文件的事件,当上传的文件为空时,使上传按钮不可用状态
this.on("removedfile", function () {
if (this.getAcceptedFiles().length === 0) {
$("#submit-all").attr("disabled", true);
}
});
}
};
</script>
</body>
后端代码
@CrossOrigin
@ApiOperation(value = "文件上传并且转为PDF", notes = "")
@PostMapping("/uploadFileToPDF")
public Result uploadFileToPDF(@RequestBody byte[] fileByte,
@RequestParam(value = "fileName",required = true) String fileName,
@RequestParam(value = "filePath",required = true) String filePath,
@RequestParam(value = "area",required = false) String area,
@RequestParam(value = "businessid",required = false) String businessid,
@RequestParam(value = "tmp_businessid",required = false) String tmp_businessid,
@RequestParam(value = "createUserId",required = false) String createUserId,
@RequestParam(value = "createUserName",required = false) String createUserName,
@RequestParam(value = "remark",required = false) String remark) {
try {
String uuid = UUID.randomUUID().toString();
// 获取文件名
String extension = getFileExtension(fileName);
String newFileName = uuid + "." + extension;
DocM_Attachment attachment = new DocM_Attachment();
attachment.setBusinessid(businessid);
attachment.setFilename(fileName);
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyMMdd");
String uploadPath = filePath + FileConnect + LocalDate.now().format(fmt);
attachment.setId(uuid);
attachment.setCreateTime(DateUtils.getNow());
attachment.setDirectory(uploadPath);
attachment.setFilepath(uploadPath + FileConnect + newFileName);
attachment.setFileSize(bytesToMegabytes((long)fileByte.length));
attachment.setArea(area);
attachment.setTmp_businessid(tmp_businessid);
attachment.setExtension(extension);
attachment.setCreateUserId(createUserId);
attachment.setCreateUserName(createUserName);
attachment.setRemark(remark);
SmbFileUtils.save(fileByte,uploadPath,newFileName);
InputStream inputStream = new ByteArrayInputStream(fileByte);
OutputStream pdfStream = null;
if(extension.equals("docx") || extension.equals("doc")){
pdfStream = doc2pdf(inputStream);
}else if(extension.equals("png") || extension.equals("jpg") || extension.equals("gif")|| extension.equals("bmp")){
pdfStream = image2pdf(inputStream);
}
DocM_Attachment pdfAttachment = new DocM_Attachment();
BeanUtils.copyProperties(attachment,pdfAttachment);
pdfAttachment.setId(UUID.randomUUID().toString());
String newPdfFileName = pdfAttachment.getId() + ".pdf";
pdfAttachment.setFilepath(uploadPath + FileConnect + newPdfFileName);
pdfAttachment.setArea("pdf");
pdfAttachment.setTmp_businessid(attachment.getId());
pdfAttachment.setFilename(fileName.split("\\.")[0] + ".pdf");
pdfAttachment.setExtension("pdf");
SmbFileUtils.save(toByteArray(pdfStream),uploadPath,newPdfFileName);
inputStream.close();
pdfStream.close();
attachmentService.add(attachment);
attachmentService.add(pdfAttachment);
return Result.success(uuid,"成功!");
} catch (Exception e) {
e.printStackTrace();
return Result.failed("文件上传失败");
}
}
知识库详情页面
左侧菜单使用JSTree.js插件,右侧文档预览使用pdf.js插件
前端代码
<!DOCTYPE html>
<html>
<head>
<title>文档管理</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="favicon.ico">
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/font-awesome.min.css" rel="stylesheet">
<link href="../css/plugins/jsTree/style.min.css" rel="stylesheet">
<link href="../css/plugins/bootstrap-table/bootstrap-table.min.css" rel="stylesheet">
<!-- 全局js -->
<script src="../js/jquery.min.js"></script>
<script src="../js/bootstrap.min.js"></script>
<script src="../js/plugins/jsTree/jstree.min.js"></script>
<script src="../js/plugins/bootstrap-table/bootstrap-table.min.js"></script>
<script src="../js/plugins/layer/layer.min.js"></script>
<script src="../js/bd-framework.js"></script>
</head>
<body class="white-bg">
<style>
.pdf
{
position:relative;
}
.main_container
{
display:flex;
}
.left_container
{
width:320px;
border-right:1px solid #e7e9e8;
overflow:scroll;
}
.right_contaner
{
flex:1;
}
#tree
{
}
.jstree-anchor {
font-size: 14px !important;
/* color:#262626 !important;*/
}
.jstree-default .jstree-node {
margin-top: 3px; /* 调整节点顶部的间距 */
margin-bottom: 3px; /* 调整节点底部的间距 */
}
.btn-power
{
display:none;
}
</style>
<div class="main_container">
<div class="left_container">
<div id="directoryExpand">
<input type="text" id="Keywords" class="form-control" placeholder="关键词搜索" />
<div style="display:flex; justify-content: space-between;align-items: center;margin-bottom:8px;padding:4px;">
<div onclick="directoryExpand()" style="font-size: 14px;color:#262626;padding-left:25px;"><i class="fa fa-bars" style="margin-right:12px;" ></i>目录</div>
<div>
<div style="position: absolute;margin-left:-90px;margin-top:-12px;" class="btn-power">
<button data-toggle="dropdown" class="btn btn-outline btn-default dropdown-toggle" type="button" aria-expanded="false">
<i class="glyphicon glyphicon-plus" aria-hidden="true"></i>
</button>
<button onclick="btn_deleteAll()" class="btn btn-outline btn-default" type="button" >
<i class="glyphicon glyphicon-trash" aria-hidden="true"></i>
</button>
<ul class="dropdown-menu pull-right">
<li>
<a href="javascript:;" onclick="btn_add()">新建分组</a>
</li>
<li>
<a href="javascript:;" onclick="btn_edit()">编辑分组</a>
</li>
<li>
<a href="javascript:;" onclick="btn_uploadFile()">上传文档</a>
</li>
</ul>
</div>
</div>
</div>
<div id="tree"></div>
</div>
<div id="directoryNoExpand" style="display:none;">
<div onclick="directoryNoExpand()" style="font-size: 14px;color:#262626;padding-left:12px;"><i class="fa fa-bars" ></i></div>
</div>
</div>
<div class="right_contaner" >
<div class="pdf" >
<iframe id="iframe1" width="100%" height="100%" src="" frameborder="0" ></iframe>
</div>
</div>
</div>
<script>
var currentNode = null;
var loadIndex = null;
function directoryExpand() {
$("#directoryExpand").hide();
$(".left_container").css("width", "40px");
$("#directoryNoExpand").show();
}
function directoryNoExpand() {
$("#directoryExpand").show();
$(".left_container").css("width", "320px");
$("#directoryNoExpand").hide();
}
$(function () {
getPower();
$(this).bind("contextmenu", function (e) {
e.preventDefault();
});
$(".left_container").height($(window).height() - 7);
$(".pdf").height($(window).height() - 7);
document.getElementById('iframe1').onload = function () {
parent.layer.close(loadIndex);
}
$("#Keywords").keydown(function (event) {
initTree();
});
})
var isManager = false;
function getPower() {
$.get("/api/DocManage/IsPowerMange", { id: GetQuery('Id') }, function (result, resultState) {
if (result.code == 200) {
$(".btn-power").show();
isManager = true;
}
initTree();
}, "json");
}
var $tree = $('#tree');
function initTree() {
if (!!GetQuery('Id')) {
var postData = {}
postData.id = GetQuery('Id');
postData.keywords = $("#Keywords").val();
$.get("/api/DocManage/GetTreeJson", postData, function (result, resultState) {
if (isManager) {
$tree
.on('activate_node.jstree', function (obj, e) {
var node = e.node;
if (node.id != undefined) {
currentNode = node;
loadPdf(node.id);
}
})
.jstree({
"multiple ": true,
'plugins': ["checkbox"],
'checkbox': {
'three_state': false,
'whole_node': false,
'tie_selection': false // 只有点击复选框才能勾选节点
},
'core': {
'data': result.data,
'check_callback': function (operation, node, node_parent, node_position, more) {
// 允许所有操作,包括创建、重命名、删除、移动和复制节点
return true;
}
}
})
} else {
$tree
.on('activate_node.jstree', function (obj, e) {
var node = e.node;
if (node.id != undefined) {
currentNode = node;
loadPdf(node.id);
}
})
.jstree({
"multiple ": true,
'core': {
'data': result.data
}
})
}
}, "json");
}
}
function loadPdf(businessid) {
loadIndex = parent.layer.msg('文档加载中,请耐心等待!', { time: 1000 * 20 });
$.get("/api/Attachment/getList?businessid="+businessid+"&area=pdf", {}, function (result, resultState) {
if (result.code == 200) {
if (result.data.length > 0) {
for (var i = 0; i < result.data.length; i++) {
if (result.data[i].EXTENSION == "pdf") {
if (result.data[i].ID != currentNode.id) {
$("#iframe1").attr("src", "../js/plugins/pdfjs-2.14.305-dist/web/DocManageViewer.html?file=" + "/api/Attachment/viewFile?id=" + result.data[i].ID);
}
break;
}
}
} else {
$("#iframe1").attr("src", "");
parent.layer.close(loadIndex);
}
}
}, "json");
}
function btn_add() {
var viewData = {};
if (currentNode) {
viewData.parentid = currentNode.id;
} else {
viewData.parentid = GetQuery('Id')
}
var layerIndex = parent.layer.open({
btn: ['确认'], //按钮
yes: function (index, layero) {
var postData = parent.$("#layui-layer-iframe" + index)[0].contentWindow.GetWebControls("#form1");
$.ajax({
url: "/api/DocManage/Save",
type: "post",
contentType: 'application/json',
data: JSON.stringify(postData),
dataType: "json",
success: function (result) {
parent.layer.close(layerIndex);
// 在选中的节点下插入新节点
$tree.jstree('create_node', currentNode, { text: result.data.name, id: result.data.id, icon: "no-icon" }, 'last', function (newNode) {
//console.log('New node created with ID:', newNode.id);
});
}
});
},
type: 2,
title: '新增',
area: ['350px', '550px'],
shadeClose: true, //开启遮罩关闭
content: '/docManage/menuEdit.html',
success: function (layero, index) {
parent.$("#layui-layer-iframe" + index)[0].contentWindow.SetWebControls(viewData);
}
});
}
function btn_edit() {
var viewData = {};
if (currentNode) {
viewData.parentid = currentNode.id;
} else {
parent.layer.msg("请选择一个分组")
return;
}
var layerIndex = parent.layer.open({
btn: ['确认', '删除'], //按钮
yes: function (index, layero) {
var postData = parent.$("#layui-layer-iframe" + index)[0].contentWindow.GetWebControls("#form1");
$.ajax({
url: "/api/DocManage/Save",
type: "post",
contentType: 'application/json',
data: JSON.stringify(postData),
dataType: "json",
success: function (result) {
parent.layer.close(layerIndex);
$tree.jstree('rename_node', currentNode, result.data.name);
}
});
}, btn2: function (index, layero) {
var index = parent.layer.confirm('是否删除?', {
btn: ['是', '否'] //按钮
}, function () {
if (currentNode) {
var postData = {};
postData.id = currentNode.id;
$.get("/api/DocManage/Delete", postData, function (result, resultState) {
if (result.code == 200) {
parent.layer.close(layerIndex);
$tree.jstree('delete_node', currentNode);
}
}, "json");
}
parent.layer.close(index);
}, function () {
parent.layer.close(index);
});
},
type: 2,
title: '编辑',
area: ['350px', '550px'],
shadeClose: true, //开启遮罩关闭
content: '/docManage/menuEdit.html',
success: function (layero, index) {
$.get("/api/DocManage/GetDetail", { id: currentNode.id }, function (result, resultState) {
parent.$("#layui-layer-iframe" + index)[0].contentWindow.SetWebControls(result.data);
}, "json");
}
});
}
function btn_deleteAll() {
var index = parent.layer.confirm('是否删除?', {
btn: ['是', '否'] //按钮
}, function () {
var postData = {};
postData.ids = getTreeSelectedData().join(',');
$.get("/api/DocManage/DeleteAll", postData, function (result, resultState) {
parent.layer.close(index);
$tree.jstree('delete_node', getTreeSelectedData());
}, "json");
}, function () {
parent.layer.close(index);
});
}
function btn_uploadFile() {
var viewData = {};
if (currentNode) {
viewData.parentid = currentNode.id;
} else {
parent.layer.msg("请选择一个分组")
return;
}
parent.layer.open({
type: 2,
title: '上传文档',
area: ['850px', '750px'],
shadeClose: true, //开启遮罩关闭
content: '/docManage/uploadFileViewToPDF.html?businessid=' + currentNode.id,
success: function (layero, index) {
}
});
}
function getTreeSelectedData() {
var nodes = $tree.jstree("get_checked"); //使用get_checked方法
return nodes;
}
</script>
</body>
文件转为pdf
使用aspose把文件转为pdf
public OutputStream doc2pdf(InputStream inputStream) throws Exception {
// 验证License 若不验证则转化出的pdf文档会有水印产生
if (!getLicense()) {
return null;
}
try {
OutputStream outputStream = new ByteArrayOutputStream();
Document doc = new Document(inputStream);
// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
doc.save(outputStream, SaveFormat.PDF);
return outputStream;
} catch (Exception e) {
e.printStackTrace();
throw new Exception("word转pdf失败");
}
}
访问nas
使用jcifs-ng访问nas
导入包
<!-- samba共享文件夹-->
<dependency>
<groupId>eu.agno3.jcifs</groupId>
<artifactId>jcifs-ng</artifactId>
<version>2.1.3</version>
</dependency>
工具栏
public class SmbFileUtils {
static String ip = "";
static String domain = "";
static String userName = "";
static String password = "";
static void SmbFileUtils(){
}
//根据账号密码登录
private static CIFSContext withNTLMCredentials(CIFSContext ctx) {
return ctx.withCredentials(new NtlmPasswordAuthenticator(domain,
userName, password));
}
//保存文件
public static String save(byte[] byteArr, String url,String fileName) throws IOException {
InputStream in = new ByteArrayInputStream(byteArr);
String status = "";
try {
CIFSContext context = withNTLMCredentials(SingletonContext.getInstance());
SmbFileWriter.createDirectory("smb://" + domain +"/" + url, context);
boolean result = SmbFileWriter.writeSmbFile(in, "smb://" + domain +"/" + url +"/" + fileName, context);
status = "success";
} catch (Exception e) {
e.printStackTrace();
status = "error";
} finally {
in.close();
return status;
}
}
//获取文件
public static InputStream getFile(String filePath) throws IOException {
String url = "smb://" + domain + "/" + filePath;
try {
CIFSContext context = withNTLMCredentials(SingletonContext.getInstance());
SmbFileReader reader = new SmbFileReader();
byte[] byteArr = reader.readSmbFile(url, context);
InputStream input = new ByteArrayInputStream(byteArr);
return input;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//删除文件
public static String delete(String filePath) throws IOException {
String status = "";
String url = "smb://" + domain + "/" + filePath;
try {
CIFSContext context = withNTLMCredentials(SingletonContext.getInstance());
SmbFile file = new SmbFile(url, context);
if (file.exists()) {
file.delete();
status = "success";
}
} catch (Exception e) {
e.printStackTrace();
status = "error";
}
return status;
}
//获取文件列表
public static List<HashMap> getPathList(String path) throws IOException {
String url = "smb://" + domain + "/" + path;
List<HashMap> filesList = new ArrayList<>();
CIFSContext context = withNTLMCredentials(SingletonContext.getInstance());
try {
SmbFile smbFile = new SmbFile(url, context);
SmbFile[] files = smbFile.listFiles();
for (SmbFile file : files) {
HashMap fileMap =new HashMap();
fileMap.put("fileName",file.getName());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 定义日期格式
fileMap.put("date",sdf.format(new Date(file.getDate())));
fileMap.put("size", String.format("%.2f", (file.length()/1024.0)/1024.0)+"MB");
fileMap.put("fileType",file.isDirectory()?"文件夹":"文件");
filesList.add(fileMap);
}
} catch (Exception e) {
e.printStackTrace();
}
return filesList;
}
static class SmbFileReader {
public byte[] readSmbFile(String path, CIFSContext context) throws IOException {
try {
SmbFile smbFile = new SmbFile(path, context);
long fileSize = smbFile.length();
if (fileSize > Integer.MAX_VALUE) {
System.out.println("file too big...");
return null;
}
InputStream fi = smbFile.getInputStream();
byte[] buffer = new byte[(int) fileSize];
int offset = 0;
int numRead = 0;
while (offset < buffer.length
&& (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) {
offset += numRead;
}
// 确保所有数据均被读取
if (offset != buffer.length) {
throw new IOException("Could not completely read file "
+ smbFile.getName());
}
fi.close();
return buffer;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
static class SmbFileWriter {
static boolean writeSmbFile(String source, String target, CIFSContext context) throws IOException {
if (StrUtils.isEmpty(source) || StrUtils.isEmpty(target)) {
return false;
}
return writeSmbFile(Files.newInputStream(Paths.get(source)),
target, context);
}
static boolean writeSmbFile(InputStream in, String target, CIFSContext context) throws IOException {
if (Objects.nonNull(in) && StrUtils.isNotEmpty(target)) {
try (SmbFile file = new SmbFile(target, context)) {
try (SmbFile parent = new SmbFile(file.getParent(), context)) {
if (!parent.exists()) {
createDirectory(file.getParent(), context);
}
if (!file.exists()) {
file.createNewFile();
}
}
try (OutputStream os = file.getOutputStream()) {
byte[] bytes = new byte[1024];
while (in.read(bytes) != -1) {
os.write(bytes);
}
return true;
}
}finally {
in.close();
}
}
return false;
}
static SmbFile createDirectory(String targetDir, CIFSContext context) throws MalformedURLException,
CIFSException, MalformedURLException {
try (SmbFile dir = new SmbFile(targetDir, context)) {
if (!dir.exists()) {
dir.mkdir();
}
return dir;
}
}
}
}