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
相关产品推荐
相关产品推荐

