【总结】前端JQuery获取Java后端文件流实现常规附件预览功能

项目背景

目前维护的项目是个远古的SpringMVC项目,前端使用的是JQuery和HTML,与Vue相比维护比较复杂,功能实现上没有那么丰富。在做附件预览的需求时,考虑不借助第三方预览服务,通过开源组件实现,需要借助以下服务依赖:
1)Java:引入aspose.words依赖(支持将word文档转换为pdf格式)
注意:需要引入license

1. Java后端处理附件

1.1 将word文档转换为pdf格式

1)在resource下新增license.xml

<License>
	<Data>
		<Products>
			<Product>Aspose.Total for Java</Product>
			<Product>Aspose.Words for Java</Product>
		</Products>
		<EditionType>Enterprise</EditionType>
		<SubscriptionExpiry>20991231</SubscriptionExpiry>
		<LicenseExpiry>20991231</LicenseExpiry>
		<SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
	</Data>
	<Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
</License>

2)word转pdf工具类

/**
 * @program: Mickey
 * @description: pdf工具类
 **/
public class WordToPdfUtil {

    public static byte[] toPdfBytes(HttpServletRequest req, InputStream inputstream) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] b = null;
        try {
            //认证aspose-word,否则转换的pdf会有水印
            if (!getWordLicense(req)) {
                return null;
            }
            LoadOptions options = new LoadOptions();
            options.setLoadFormat(LoadFormat.DOC);
            Document doc = new Document(inputstream, options);
            doc.save(bos, SaveFormat.PDF);
            b = bos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("word转换pdf出错!");
        } finally {
            bos.close();
        }
        return b;
    }

    /**
     * 获取aspose-word授权
     *
     * @return
     */
    public static boolean getWordLicense(HttpServletRequest req) {
        boolean result = false;
        InputStream is = null;
        try {
            //获取认证文件,并转为输入流
            is = new FileInputStream(req.getSession().getServletContext().getRealPath("") + File.separator + "downFile/pdfFile" + File.separator + "license.xml");
            //创建密钥认证对象
            License aposeLic = new License();
            //进行认证ss
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}

1.2 将文件流返回前端

try (InputStream in = new FileInputStream(new File("文件路径"))) {
	// 预览附件类型白名单
    List<String> whiteFileTypeList = Arrays.asList(DOC_SUFFIX, DOCX_SUFFIX, PDF_SUFFIX, TXT_SUFFIX, OFD_SUFFIX, PNG_SUFFIX, JPG_SUFFIX, JPEG_SUFFIX);
    // 不支持附件预览的类型
    if (StringUtils.isNotBlank(suffix) && !whiteFileTypeList.contains(suffix)) {
        throw new RuntimeException("不支持的附件预览类型,请下载后查看!");
    }
    String fileName = "预览附件名称";
    byte[] toPdfBytes;
    // word文档类型进行格式转换
    if (StringUtils.equals(DOC_SUFFIX, suffix) || StringUtils.equals(DOCX_SUFFIX, suffix)) {
        toPdfBytes = WordToPdfUtil.toPdfBytes(request, in);
    } else {
        toPdfBytes = readInputStream(in);
        if (StringUtils.equals(PNG_SUFFIX, suffix) || StringUtils.equals(JPG_SUFFIX, suffix) || StringUtils.equals(JPEG_SUFFIX, suffix)) {
            String base64Str = Base64Utils.encodeToString(toPdfBytes);
            model.put("base64Str", base64Str);
        }
        if (StringUtils.equals(TXT_SUFFIX, suffix)) {
            model.put("txtView", toPdfBytes);
        }
    }
    if (toPdfBytes != null) {
        try {
            String contextPath = request.getContextPath();
            String basePath = request.getSession().getServletContext().getRealPath(File.separator);
            File outFile = new File(basePath + File.separator + "temp" + File.separator + "fileView");
            if (!outFile.isDirectory()) {
                if (!outFile.exists()) {
                    boolean b = outFile.mkdirs();
                }
            }
            FileOutputStream fo = new FileOutputStream(outFile + File.separator + "附件id" + ".pdf");
            BufferedOutputStream out = new BufferedOutputStream(fo);
            out.write(toPdfBytes, 0, toPdfBytes.length);
            out.flush();
            out.close();
            return contextPath + File.separator + "temp" + File.separator + "fileView" + File.separator + "附件id" + ".pdf";
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
} catch (IOException e) {
    log.error("附件处理异常", e);
} 

2. 前端处理附件预览(JQuery)

2.1 预览pdf文件

引入PDFView组件

<iframe id="pdfFrame" src="${base}/pdfView/web/viewer.html?file=${viewFilePath}" width="900" height="530"></iframe>

2.2 预览ofd文件

引入ofd.js依赖,支持ofd文件查看

<div class="ofdContainer" id="ofdContainer" style="width: 900px; height: 530px; overflow-y: scroll;"></div>
$(function() {
  // ofd文件预览
  if (suffix && suffix === 'ofd') {
    var xhr = new XMLHttpRequest();
    xhr.open('POST', '附件下载地址', true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.responseType = 'blob';
    xhr.send("id=" + 附件id);
    xhr.onload = function(e) {
      if (this.status === 200) {
        var blob = new Blob([this.response], {type: 'application/ofd'});
        // 处理文件流,比如使用 FileReader 进行读取或者直接下载
        const file = new File([blob], fileName + '.ofd', { type: blob.type });
        ofd.parseOfdDocument({
          ofd: file,
          success: function (res) {
            const screenWidth = 800;
            const ofdRenderRes = ofd.renderOfd(screenWidth, res[0]);
            let ofdContainerDiv = document.getElementById('ofdContainer');
            // 清空元素
            ofdContainerDiv.innerHTML = '';
            for (const item of ofdRenderRes) {
              ofdContainerDiv.appendChild(item);
            }
          },
          fail: function (err) {
            console.error(err);
          },
        });
      }
    };
  }
})

2.3 预览图片、txt文档

1)将后端获取的文件流转换为Base64格式,前端展示图片

<img src="data:image/jpeg;base64,${base64Str!}" style="width: 900px; height: 530px; overflow-y: scroll;" />

2)展示txt文档

<pre class="txtContainer" id="txtContainer" style="width: 900px; height: 530px; overflow-y: scroll; text-align: left;"></pre>
fetch('替换为你的后端TXT文件下载地址' + 附件id)
    .then(response => response.text())
    .then(text => {
      document.getElementById('txtContainer').textContent = text;
    })
    .catch(error => console.error('读取文件出错:', error));

共勉。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java后端中,可以使用Java的File类和ImageIO类读取本地图片,然后将图片以的形式返回。在Layui前端中,可以使用Ajax技术向Java后端发送请求,然后将返回的图片显示在页面上。以下是示例代码: Java后端代码: ```java import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class ImageController { @RequestMapping(value = "/image", method = RequestMethod.GET, produces = "image/jpeg") @ResponseBody public byte[] getImageAsBytes(@RequestParam("name") String imageName) throws IOException { Resource resource = new ClassPathResource("images/" + imageName); File file = resource.getFile(); BufferedImage bufferedImage = ImageIO.read(file); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream); return byteArrayOutputStream.toByteArray(); } } ``` 在这个示例中,我们使用了Spring框架的`@Controller`注解和`@RequestMapping`注解,以便在URL路径中接收图片的名称。`@ResponseBody`注解告诉Spring将返回的字节数组转换成HTTP响应。我们使用Spring的`Resource`类和`ClassPathResource`类来加载本地图片,然后使用和之前示例一样的方式将其转换成字节数组返回。注意,这个示例中我们将图片放在了`src/main/resources/images`目录下。 前端代码: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>显示图片</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/layer/3.1.1/layer.min.js"></script> </head> <body> <img id="image" src="" alt="图片"> <script type="text/javascript"> $(function() { var imageName = "myimage.jpg"; // 图片名称 var url = "/image?name=" + imageName; // 请求图片的URL $.ajax({ type: "GET", url: url, success: function(data) { var blob = new Blob([data], {type: "image/jpeg"}); // 将字节数组转换成Blob对象 var objectUrl = URL.createObjectURL(blob); // 创建URL对象 $("#image").attr("src", objectUrl); // 在页面上显示图片 }, error: function() { layer.msg("获取图片失败"); } }); }); </script> </body> </html> ``` 这个示例中,我们使用了jQuery和Layer插件。在页面加载完成后,使用Ajax向Java后端发送请求,获取图片并将其显示在页面上。注意,这个示例中的图片名称是硬编码的,你需要根据实际情况修改代码来适应你的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值