You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AngularJS多文件上传:PDF无法预览问题的解决方案请求

解决AngularJS中PDF文件预览的问题

你遇到的核心问题是图片标签<img>无法渲染PDF文件——它只支持图片格式。要实现PDF预览,我们需要根据选中文件的类型,动态切换预览组件(图片用<img>,PDF用<embed>或<iframe>)。下面是具体的修改方案:

第一步:更新HTML结构

我们需要修改文件选择器的accept属性支持PDF,同时在预览区域根据文件类型渲染不同的元素:

<div class="container">
 <div ng-controller="MyCtrl" class="row">
 <button class="btn btn-primary pull-right" ng-hide="files.length == 0" ng-click="clearAll()">Clear All</button>
 <h3 ng-bind="name"></h3>
 <!-- 增加PDF的accept类型 -->
 <input type="file" ng-click="$event = $event" ng-model="displayItem" multiple onchange="angular.element(this).scope().upload(event)" accept="image/png, image/jpeg, image/gif, application/pdf" />
 <div class="row">
 <div class="col-md-12">
 <span ng-repeat='item in files'>
 <a href="#" ng-click="setDisplayItem($index)">
 <!-- 根据文件类型切换预览组件 -->
 <img ng-if="item.isImage" ng-src="{{item.dataUrl}}" alt="Image thumbnail" style="max-height:100px;" class="thumbnail"/>
 <embed ng-if="!item.isImage" src="{{item.dataUrl}}" type="application/pdf" style="max-height:100px; width: 80px;" class="thumbnail"/>
 </a>
 </span>
 </div>
 </div>
 <!-- 主预览区域同样区分类型 -->
 <img ng-if="displayItem.isImage" ng-src="{{displayItem.dataUrl}}" ng-hide="!displayItem" />
 <embed ng-if="!displayItem.isImage" src="{{displayItem.dataUrl}}" type="application/pdf" ng-hide="!displayItem" style="width: 100%; height: 500px;"/>
 <h4>You have uploaded {{files.length}} files this session. </h4>
 </div>
</div>

第二步:修改JS逻辑

现在我们需要在上传时记录每个文件的类型(判断是否为图片),而不是只存DataURL:

var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function ($scope) {
 $scope.name = "Select Files to Upload";
 // 把images数组改成files,存储包含文件类型和DataURL的对象
 $scope.files = [];
 $scope.displayItem = null;

 $scope.setDisplayItem = function (ix) {
 $scope.displayItem = $scope.files[ix];
 }

 $scope.clearAll = function () {
 $scope.displayItem = null;
 $scope.files = [];
 }

 $scope.upload = function (obj) {
 var elem = obj.target || obj.srcElement;
 for (let i = 0; i < elem.files.length; i++) { // 用let避免闭包问题
 var file = elem.files[i];
 var reader = new FileReader();
 // 先判断文件是否为图片
 const isImage = file.type.startsWith('image/');
 reader.onload = function (e) {
 $scope.files.push({
 dataUrl: e.target.result,
 isImage: isImage
 });
 // 默认显示最后一个上传的文件
 $scope.displayItem = $scope.files[$scope.files.length - 1];
 $scope.$apply();
 }
 reader.readAsDataURL(file);
 }
 }
})

关键说明

  • 文件类型判断:通过file.type.startsWith('image/')来区分图片和PDF(以及其他文件),确保我们用正确的组件渲染。
  • PDF预览组件:使用<embed>标签是因为它原生支持PDF渲染,也可以换成<iframe>,效果类似。
  • 变量名调整:把images改成files更贴合现在支持多文件类型的场景,避免语义混淆。
  • 闭包问题修复:把循环里的i改成let,避免所有reader回调都引用最后一个文件的问题。

这样修改后,你就能同时预览图片和PDF文件了,而且保留了原有的多文件上传、选中预览、清空所有功能。

内容的提问来源于stack exchange,提问作者User

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:22:27