Java文件上传数据库(并保存本地)、word转pdf并进行页面预览

对于页面预览用到了OpenOffice附件:
官方的下载地址:Apache OpenOffice
选择windows版本安装完成后,在cmd中执行下面两个命令,查看任务管理器中是否有soffice.bin的进程。(用到OpenOffice,必须保证任务管理器中有soffice.bin的进程)

cd  C:\Program Files (x86)\OpenOffice 4\program

soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard

在这里插入图片描述
在这里插入图片描述
各别情况OpenOffice会杀掉自己的进程,所以也可以配置成Windows服务。
参考上一篇:OpenOffice注册windows服务
下面进行具体说明:
1.导入jar包:用gradle导入+本地jar导入:
gradle里配置如下:
在这里插入图片描述
(1.)OpenOffice转换jar:
compile(“org.jodconverter:jodconverter-core:4.2.0”)
compile(“org.openoffice:juh:4.1.2”)
compile(“org.openoffice:jurt:4.1.2”)
compile(“org.openoffice:ridl:4.1.2”)
compile(“org.openoffice:unoil:4.1.2”)
compile(“com.thoughtworks.xstream:xstream:1.4.10”)
//compile(“com.artofsolving:jodconverter:2.2.2”)
这些只需在gradle里写好依赖,直接远程下载包。
(2.)word文档转换pdf格式工具架包:jodconverter-2.2.2.jar
compile fileTree(dir:‘lib’,include:[’*.jar’])
解析:获取lib文件夹下所有jar包
jodconverter-2.2.2.jar下载:https://pan.baidu.com/s/1z0lWuX8spH8aVTo48NCVQw 密码:jndj
(找到lib文件夹下对应的jar)
这个远程下载如果有问题,就需要本地导入,在项目根路径下新建一个lib文件夹,将要导入的jar包拖进去,刷新gradle,显示下面图片表示成功。
在这里插入图片描述
2.文件上传数据库临时表(并保存本地)
a.建立临时表(log_file),存放文件信息。(这里用的表示之前项目用的,没做修改。)
在这里插入图片描述
b.建立对应实体类,Setter and Getter。
c.编写主要接口方法:

//文件上传数据库临时表
public LogFile upload(InputStream inputStream, String name, String fileType, String subType, String keyId, String fileSource, String userIdAndName) throws IOException;

d.编写实现类方法:
在程序中获取某个文件的绝对路径,@Value("${app.file.uploadPath:}")通过注解方式加载properties文件;在application.yml中配置文件路径,如图:
在这里插入图片描述
具体代码如下:

@Service
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public class FileServiceImpl extends BaseService implements FileService {
    @Value("${app.file.uploadPath:}")
    private String uploadPath;

    @Autowired
    private LogFileDao logFileDao;

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public LogFile upload(InputStream inputStream, String name, String fileType, String subType, String keyId, String fileSource, String userIdAndName) throws IOException {
        // TODO: inputStream不能多次读取,因此先读出来
        // TODO: 下一步考虑是否从文件内容获取文件类型,而不是根据文件名
        byte[] bytes = FileUtil.read(inputStream);
        int fileSize = bytes.length;
        String md5 = DigestUtils.md5Hex(bytes);
        String sha1 = DigestUtils.sha1Hex(bytes);
        Example example = new Example(LogFile.class);
        example.createCriteria().andEqualTo("fileMd5", md5);
        List<LogFile> list = logFileDao.selectByExample(example);
        String sign = md5;
        if (list != null) {
            if(list.size()  == 1){
            // 存在md5相同的记录,需要判断sign
            LogFile savedFile = list.get(0);
            //判断服务器目录下是否有文件,数据库中有上传记录,但实际服务器目录无文件,读取文件时无法找到文件,无实际意义
            File file  =  new File(savedFile.getFilePath()+savedFile.getFileName());
            if (savedFile.getFileSha1() != null && savedFile.getFileSha1().equals(sha1) && savedFile.getFileSize() != null && savedFile.getFileSize() == fileSize) {
                savedFile.setFilePath("******");
                //如果文件不存在,可以上传文件  
                if(!file.exists()){
                    FileUtil.save(bytes, new FileOutputStream(savedFile.getFilePath()+savedFile.getFileName()));
                }
                return savedFile;
            }
               sign = md5 + sha1 + DigestUtils.md5Hex(String.valueOf(fileSize));
            //如果出现多条的情况,直接清空表md5相同的日志记录,后面重新插入
            }else{
                logFileDao.deleteByExample(example);
            }
        }

        String extName = name.substring(name.lastIndexOf(".") + 1);
        String fileName = StringUtil.guid() + "." + extName;
        String filePath = FileUtil.filePath(uploadPath);

        // inputStream上面读取后,不能直接用
        FileUtil.save(bytes, new FileOutputStream(filePath + fileName));

        LogFile logFile = new LogFile();
        logFile.setFileId(StringUtil.guid());
        logFile.setFileType(fileType);
        logFile.setSubType(subType);
        logFile.setKeyId(keyId);
        logFile.setFileName(fileName);
        logFile.setOriginName(name);
        logFile.setFilePath(filePath);
        // fileDescribe
        logFile.setExtName(extName);
        // extType
        logFile.setFileSize(fileSize);
        // thumbName
        logFile.setImageWidth(0);
        logFile.setImageHeight(0);
        logFile.setFileMd5(md5);
        logFile.setFileSha1(sha1);
        logFile.setFileSign(sign);
        logFile.setFileSource(fileSource);
        // deleteTime
        // deleteUser
        logFile.setFileState("0000");
        // areaCode
        // appCode
        logFile.setManageTime(DateUtil.getDateDate());
        logFile.setManageUser(userIdAndName);
		//将文件信息插入log_file临时表
        logFileDao.insert(logFile);

        // 隐藏文件路径
        logFile.setFilePath("******");

        return logFile;
  		 }
   }

e.编写控制器类:

@RequestMapping(value="/upload", method = RequestMethod.POST)
    public LogFile upload(@RequestParam(name = "name") String name, @RequestParam(name = "fileType", required = false) String fileType, @RequestParam(name = "subType", required = false) String subType,
                          @RequestParam(name = "keyId", required = false) String keyId, @RequestParam(name = "fileSource", required = false) String fileSource, HttpServletRequest httpServletRequest) throws IOException {
        return fileService.upload(httpServletRequest.getInputStream(), name, fileType, subType, keyId, fileSource, super.getUserIdAndName());
    }

以上文件上传逻辑完成:
e-1:整个逻辑应用了文件流,用MD5对fileId、filesign等进行加密。涉及了一个简单查询,一个删除接口上面没有完全体现。(每次上传文件是存到临时表,上传前会判断文件是否存在,如果出现多条的情况,直接清空表md5相同的日志记录,后面重新插入)
e-2:文件保存数据库同时,会在application.yml配置的文件路径下生成对应文件。

3.上传数据库表(并保存本地,与上同路径),word转pdf
a.建立数据库表Test
在这里插入图片描述
b.建立对应实体类,Setter and Getter。
c.编写主要接口方法:

//上传文件到数据库表
void worldImport(Test test);

d.编写接口实现类方法:

public class TestServiceImpl extends BaseService implements TestService{
	@Autowired
    private TestDao testDao;
	@Override
    public void worldImport(Test test) {
        testDao.insertNotNull(test);
    }
}

e.编写word转pdf工具类:

public class OpenOfficeUtil {
    public static String wordToPDF(String filePath,String fileName){
        File docFile = new File(filePath+fileName);
        File pdfFile = null;
        if (fileName.contains(".")){
            pdfFile = new File(filePath+fileName.substring(0,fileName.indexOf("."))+"pdf.pdf");
        }else {
            pdfFile = new File(filePath+fileName+"pdf.pdf");
        }
        String pdfFilePath = pdfFile.getPath();
        if (docFile.exists()){
            if (!pdfFile.exists()){
                OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
                try {
                    connection.connect();
                    DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
                    converter.convert(docFile,pdfFile);
                    connection.disconnect();
                } catch (ConnectException e) {
                    e.printStackTrace();
                }
            }else {
                throw new RuntimeException("该文件已经转换过了!");
            }
        }else {
            throw new RuntimeException("需要转换的文件不存在!");
        }
        return pdfFilePath;
    }
}

f.编写控制器类:

@RequestMapping(value = "/worldImport",method = RequestMethod.POST)
    public void worldImport(@RequestBody String  fileSign) throws IOException, InvalidFormatException, SAXException {
        if(StringUtils.isEmpty(fileSign)){
            return;
        }
        LogFile logFile =  fileService.selectBySign(fileSign);
        if(logFile == null){
            return;
        }
        //将Word文档转化为PDF文档
        String pdfFilePath = OpenOfficeUtil.wordToPDF(logFile.getFilePath(),logFile.getFileName());
        System.err.println(pdfFilePath);
        FileInputStream fileInputStream = new FileInputStream(pdfFilePath);
        byte[] content = new byte[fileInputStream.available()];
        fileInputStream.read(content);
        Test test = new Test();
        test.setTest(content);
        testServiceImpl.worldImport(test);
        fileInputStream.close();
    }

以上文件上传、word转pdf逻辑完成:
实现:通过调用临时表log_file信息(路径+名字),将需要转换的word文件转换成pdf文件,转格式存放在数据库表test中,同时在本地生成对应pdf文件。
4.对pdf文件进行预览
a.编写接口方法:

List<Test> world();

b.编写实现类方法:

@Override
    public List<Test> world() {
        return testDao.selectAll();
    }

c.编写控制器类:

@RequestMapping(value = "/world",method = RequestMethod.GET)
    public void world(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException {
        List<Test> tests = testServiceImpl.world();
        //具体需求具体判断,此处获取的是数据库第六条数据的文件信息。
        byte[] result = tests.get(7).getTest();
        ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream();
        if (servletOutputStream != null && result != null){
            httpServletResponse.setContentType("application/pdf");
            httpServletResponse.setContentLength(result.length);
            httpServletResponse.setHeader("Expires","0");
            httpServletResponse.setHeader("Cache-Control","must-revalidate,post-check=0,pre-check=0");
            httpServletResponse.setHeader("Pragma","public");
            servletOutputStream.write(result);
            servletOutputStream.flush();
            servletOutputStream.close();
        }
    }

以上整个逻辑完成,主要参考代码如上,部分工具类下篇总结。页面展示如下:
在这里插入图片描述

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸟驿站ㅤ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值