나는 Angular의 초보자이며 Angular 5 File upload part 만드는 법을 알고 싶습니다. 튜토리얼이나 문서를 찾으려고하지만 아무데도 보이지 않습니다. 이것에 대한 아이디어가 있습니까? 그리고 ng4 파일을 시도했지만 Angular 5에서는 작동하지 않습니다.
나는 Angular의 초보자이며 Angular 5 File upload part 만드는 법을 알고 싶습니다. 튜토리얼이나 문서를 찾으려고하지만 아무데도 보이지 않습니다. 이것에 대한 아이디어가 있습니까? 그리고 ng4 파일을 시도했지만 Angular 5에서는 작동하지 않습니다.
답변:
다음은 API로 파일을 업로드하는 실제 예입니다.
1 단계 : HTML 템플릿 (file-upload.component.html)
유형의 간단한 입력 태그를 정의하십시오 file
. (change)
파일 선택을 처리 하기 위해 -event에 함수를 추가 하십시오.
<div class="form-group">
<label for="file">Choose File</label>
<input type="file"
id="file"
(change)="handleFileInput($event.target.files)">
</div>
2 단계 : TypeScript에서 업로드 처리 (file-upload.component.ts)
선택한 파일의 기본 변수를 정의하십시오.
fileToUpload: File = null;
(change)
파일 입력 태그의 -event 에서 사용하는 함수를 작성하십시오 .
handleFileInput(files: FileList) {
this.fileToUpload = files.item(0);
}
다중 파일 선택을 처리하려면이 파일 배열을 반복 할 수 있습니다.
이제 file-upload.service를 호출하여 파일 업로드 기능을 작성하십시오.
uploadFileToActivity() {
this.fileUploadService.postFile(this.fileToUpload).subscribe(data => {
// do something, if upload success
}, error => {
console.log(error);
});
}
3 단계 : 파일 업로드 서비스 (file-upload.service.ts)
POST 메소드를 통해 파일을 업로드하면 FormData
http 요청에 파일을 추가 할 수 있으므로를 사용해야합니다 .
postFile(fileToUpload: File): Observable<boolean> {
const endpoint = 'your-destination-url';
const formData: FormData = new FormData();
formData.append('fileKey', fileToUpload, fileToUpload.name);
return this.httpClient
.post(endpoint, formData, { headers: yourHeadersConfig })
.map(() => { return true; })
.catch((e) => this.handleError(e));
}
그래서 이것은 매우 간단한 작업 예입니다. 나는 매일 업무에 사용합니다.
const invFormData: FormData = new FormData(); invFormData.append('invoiceAttachment', invoiceAttachment, invoiceAttachment.name); invFormData.append('invoiceInfo', JSON.stringify(invoiceInfo));
. 컨트롤러에는 두 개의 해당 매개 변수가 있지만 컨트롤러에서 JSON을 구문 분석해야했습니다. My Core 2 컨트롤러는 매개 변수에서 모델을 자동으로 픽업하지 않습니다. 내 원래 디자인은 파일 속성을 가진 모델이지만 작동하지 못했습니다.
createContrat(fileToUpload: File, newContrat: Contrat): Observable<boolean> { let headers = new Headers(); const endpoint = Api.getUrl(Api.URLS.createContrat)); const formData: FormData =new FormData(); formData.append('fileKey', fileToUpload, FileToUpload.name); let body newContrat.gup(this.auth.getCurrentUser().token); return this.http .post(endpoint, formData, body) .map(() => { return true; }) }
Content-Disposition: form-data; name="fileKey"; filename="file.docx" Content-Type: application/octet-stream <file>
이 방법으로 프로젝트에서 웹 API로 파일 업로드를 구현합니다.
나는 누구의 관심사를 공유합니다.
const formData: FormData = new FormData();
formData.append('Image', image, image.name);
formData.append('ComponentId', componentId);
return this.http.post('/api/dashboard/UploadImage', formData);
단계별
ASP.NET 웹 API
[HttpPost]
[Route("api/dashboard/UploadImage")]
public HttpResponseMessage UploadImage()
{
string imageName = null;
var httpRequest = HttpContext.Current.Request;
//Upload Image
var postedFile = httpRequest.Files["Image"];
//Create custom filename
if (postedFile != null)
{
imageName = new String(Path.GetFileNameWithoutExtension(postedFile.FileName).Take(10).ToArray()).Replace(" ", "-");
imageName = imageName + DateTime.Now.ToString("yymmssfff") + Path.GetExtension(postedFile.FileName);
var filePath = HttpContext.Current.Server.MapPath("~/Images/" + imageName);
postedFile.SaveAs(filePath);
}
}
HTML 양식
<form #imageForm=ngForm (ngSubmit)="OnSubmit(Image)">
<img [src]="imageUrl" class="imgArea">
<div class="image-upload">
<label for="file-input">
<img src="upload.jpg" />
</label>
<input id="file-input" #Image type="file" (change)="handleFileInput($event.target.files)" />
<button type="submit" class="btn-large btn-submit" [disabled]="Image.value=='' || !imageForm.valid"><i
class="material-icons">save</i></button>
</div>
</form>
API를 사용하는 TS 파일
OnSubmit(Image) {
this.dashboardService.uploadImage(this.componentId, this.fileToUpload).subscribe(
data => {
console.log('done');
Image.value = null;
this.imageUrl = "/assets/img/logo.png";
}
);
}
서비스 TS
uploadImage(componentId, image) {
const formData: FormData = new FormData();
formData.append('Image', image, image.name);
formData.append('ComponentId', componentId);
return this.http.post('/api/dashboard/UploadImage', formData);
}
매우 쉽고 빠른 방법은 ng2-file-upload를 사용하는 것 입니다.
npm을 통해 ng2-file-upload를 설치하십시오. npm i ng2-file-upload --save
처음에는 모듈에서 모듈을 가져옵니다.
import { FileUploadModule } from 'ng2-file-upload';
Add it to [imports] under @NgModule:
imports: [ ... FileUploadModule, ... ]
마크 업 :
<input ng2FileSelect type="file" accept=".xml" [uploader]="uploader"/>
당신의 comptponent ts에서 :
import { FileUploader } from 'ng2-file-upload';
...
uploader: FileUploader = new FileUploader({ url: "api/your_upload", removeAfterUpload: false, autoUpload: true });
가장 간단한 사용법입니다. 이 모든 힘을 알기 위해서는 데모를 참조하십시오
Angular 5.2.11을 사용하고 있습니다. Gregor Doroschenko가 제공 한 솔루션이 마음에 들지만 업로드 된 파일의 바이트가 0임을 알았습니다. 제대로 작동하려면 약간 변경해야했습니다.
postFile(fileToUpload: File): Observable<boolean> {
const endpoint = 'your-destination-url';
return this.httpClient
.post(endpoint, fileToUpload, { headers: yourHeadersConfig })
.map(() => { return true; })
.catch((e) => this.handleError(e));
}
다음 줄 (formData)이 작동하지 않았습니다.
const formData: FormData = new FormData();
formData.append('fileKey', fileToUpload, fileToUpload.name);
https://github.com/amitrke/ngrke/blob/master/src/app/services/fileupload.service.ts
이 스레드는 Google의 첫 번째 결과와 동일한 질문을 가진 다른 사용자에게 표시되므로 trueboroda가 지적한대로 바퀴를 되 돌리지 않아도 ng2-file-upload 라이브러리가 있습니다. 각도 6과 7이있는 파일은 다음과 같습니다.
최신 Angular CLI 설치
yarn add global @angular/cli
그런 다음 호환성 문제를 위해 rx-compat를 설치하십시오.
npm install rxjs-compat --save
ng2- 파일 업로드 설치
npm install ng2-file-upload --save
모듈에서 FileSelectDirective 지시문을 가져 오십시오.
import { FileSelectDirective } from 'ng2-file-upload';
Add it to [declarations] under @NgModule:
declarations: [ ... FileSelectDirective , ... ]
구성 요소에서
import { FileUploader } from 'ng2-file-upload/ng2-file-upload';
...
export class AppComponent implements OnInit {
public uploader: FileUploader = new FileUploader({url: URL, itemAlias: 'photo'});
}
주형
<input type="file" name="photo" ng2FileSelect [uploader]="uploader" />
이해를 돕기 위해이 링크를 확인할 수 있습니다 : Angular 6/7로 파일을 업로드하는 방법
개인적으로 프론트 엔드에는 ngx-material-file-input , 백엔드는 Firebase 를 사용 하여이 작업을 수행하고 있습니다. Cloud Firestore와 결합 된 백엔드 용 Firebase for Firebase 를 보다 정확하게 말하십시오. 아래의 예에서는 파일이 20MB 이하로 제한되고 특정 파일 확장자 만 허용합니다. 또한 업로드 된 파일에 대한 링크를 저장하기 위해 Cloud Firestore 를 사용 하고 있지만이를 건너 뛸 수 있습니다.
contact.component.html
<mat-form-field>
<!--
Accept only files in the following format: .doc, .docx, .jpg, .jpeg, .pdf, .png, .xls, .xlsx. However, this is easy to bypass, Cloud Storage rules has been set up on the back-end side.
-->
<ngx-mat-file-input
[accept]="[
'.doc',
'.docx',
'.jpg',
'.jpeg',
'.pdf',
'.png',
'.xls',
'.xlsx'
]"
(change)="uploadFile($event)"
formControlName="fileUploader"
multiple
aria-label="Here you can add additional files about your project, which can be helpeful for us."
placeholder="Additional files"
title="Additional files"
type="file"
>
</ngx-mat-file-input>
<mat-icon matSuffix>folder</mat-icon>
<mat-hint
>Accepted formats: DOC, DOCX, JPG, JPEG, PDF, PNG, XLS and XLSX,
maximum files upload size: 20 MB.
</mat-hint>
<!--
Non-null assertion operators are required to let know the compiler that this value is not empty and exists.
-->
<mat-error
*ngIf="contactForm.get('fileUploader')!.hasError('maxContentSize')"
>
This size is too large,
<strong
>maximum acceptable upload size is
{{
contactForm.get('fileUploader')?.getError('maxContentSize')
.maxSize | byteFormat
}}</strong
>
(uploaded size:
{{
contactForm.get('fileUploader')?.getError('maxContentSize')
.actualSize | byteFormat
}}).
</mat-error>
</mat-form-field>
contact.component.ts (크기 검사기 부분)
import { FileValidator } from 'ngx-material-file-input';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
/**
* @constructor
* @description Creates a new instance of this component.
* @param {formBuilder} - an abstraction class object to create a form group control for the contact form.
*/
constructor(
private angularFirestore: AngularFirestore,
private angularFireStorage: AngularFireStorage,
private formBuilder: FormBuilder
) {}
public maxFileSize = 20971520;
public contactForm: FormGroup = this.formBuilder.group({
fileUploader: [
'',
Validators.compose([
FileValidator.maxContentSize(this.maxFileSize),
Validators.maxLength(512),
Validators.minLength(2)
])
]
})
contact.component.ts (파일 업 로더 부분)
import { AngularFirestore } from '@angular/fire/firestore';
import {
AngularFireStorage,
AngularFireStorageReference,
AngularFireUploadTask
} from '@angular/fire/storage';
import { catchError, finalize } from 'rxjs/operators';
import { throwError } from 'rxjs';
public downloadURL: string[] = [];
/**
* @description Upload additional files to Cloud Firestore and get URL to the files.
* @param {event} - object of sent files.
* @returns {void}
*/
public uploadFile(event: any): void {
// Iterate through all uploaded files.
for (let i = 0; i < event.target.files.length; i++) {
const randomId = Math.random()
.toString(36)
.substring(2); // Create random ID, so the same file names can be uploaded to Cloud Firestore.
const file = event.target.files[i]; // Get each uploaded file.
// Get file reference.
const fileRef: AngularFireStorageReference = this.angularFireStorage.ref(
randomId
);
// Create upload task.
const task: AngularFireUploadTask = this.angularFireStorage.upload(
randomId,
file
);
// Upload file to Cloud Firestore.
task
.snapshotChanges()
.pipe(
finalize(() => {
fileRef.getDownloadURL().subscribe((downloadURL: string) => {
this.angularFirestore
.collection(process.env.FIRESTORE_COLLECTION_FILES!) // Non-null assertion operator is required to let know the compiler that this value is not empty and exists.
.add({ downloadURL: downloadURL });
this.downloadURL.push(downloadURL);
});
}),
catchError((error: any) => {
return throwError(error);
})
)
.subscribe();
}
}
storage.rules
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read; // Required in order to send this as attachment.
// Allow write files Firebase Storage, only if:
// 1) File is no more than 20MB
// 2) Content type is in one of the following formats: .doc, .docx, .jpg, .jpeg, .pdf, .png, .xls, .xlsx.
allow write: if request.resource.size <= 20 * 1024 * 1024
&& (request.resource.contentType.matches('application/msword')
|| request.resource.contentType.matches('application/vnd.openxmlformats-officedocument.wordprocessingml.document')
|| request.resource.contentType.matches('image/jpg')
|| request.resource.contentType.matches('image/jpeg')
|| request.resource.contentType.matches('application/pdf')
|| request.resource.contentType.matches('image/png')
|| request.resource.contentType.matches('application/vnd.ms-excel')
|| request.resource.contentType.matches('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'))
}
}
}
toString()
contactForm 선언에 왜 필요한 가요?
toString()
쓸모 없고 내 대답을 편집 했습니다 . 의 끝이 댓글을 읽을 것이다 사람들의 경우 fileUploader
에 contact.component.ts 내가했다 ])].toString()})
. 이제는 간단합니다 : ])]})
.
<div class="form-group">
<label for="file">Choose File</label><br /> <input type="file" id="file" (change)="uploadFiles($event.target.files)">
</div>
<button type="button" (click)="RequestUpload()">Ok</button>
public formData = new FormData();
ReqJson: any = {};
uploadFiles( file ) {
console.log( 'file', file )
for ( let i = 0; i < file.length; i++ ) {
this.formData.append( "file", file[i], file[i]['name'] );
}
}
RequestUpload() {
this.ReqJson["patientId"] = "12"
this.ReqJson["requesterName"] = "test1"
this.ReqJson["requestDate"] = "1/1/2019"
this.ReqJson["location"] = "INDIA"
this.formData.append( 'Info', JSON.stringify( this.ReqJson ) )
this.http.post( '/Request', this.formData )
.subscribe(( ) => {
});
}
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class Request {
private static String UPLOADED_FOLDER = "c://temp//";
@PostMapping("/Request")
@ResponseBody
public String uploadFile(@RequestParam("file") MultipartFile file, @RequestParam("Info") String Info) {
System.out.println("Json is" + Info);
if (file.isEmpty()) {
return "No file attached";
}
try {
// Get the file and save it somewhere
byte[] bytes = file.getBytes();
Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
Files.write(path, bytes);
} catch (IOException e) {
e.printStackTrace();
}
return "Succuss";
}
}
C 드라이브에 "temp"폴더를 만들어야합니다. 그러면이 코드는 콘솔에서 Json을 인쇄하고 생성 된 폴더에 업로드 된 파일을 저장합니다
먼저 Angular 프로젝트에서 HttpClient를 설정해야합니다.
src / app / app.module.ts 파일을 열고 HttpClientModule을 가져온 후 다음과 같이 모듈의 imports 배열에 추가하십시오.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
다음으로 컴포넌트를 생성하십시오.
$ ng generate component home
다음으로 업로드 서비스를 생성하십시오.
$ ng generate service upload
다음으로 src / app / upload.service.ts 파일을 다음과 같이여십시오 :
import { HttpClient, HttpEvent, HttpErrorResponse, HttpEventType } from '@angular/common/http';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class UploadService {
SERVER_URL: string = "https://file.io/";
constructor(private httpClient: HttpClient) { }
public upload(formData) {
return this.httpClient.post<any>(this.SERVER_URL, formData, {
reportProgress: true,
observe: 'events'
});
}
}
그런 다음 src / app / home / home.component.ts 파일을 열고 다음 가져 오기를 추가하여 시작하십시오.
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { HttpEventType, HttpErrorResponse } from '@angular/common/http';
import { of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { UploadService } from '../upload.service';
다음으로 fileUpload 및 files 변수를 정의하고 다음과 같이 UploadService를 삽입하십시오.
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
@ViewChild("fileUpload", {static: false}) fileUpload: ElementRef;files = [];
constructor(private uploadService: UploadService) { }
다음으로 uploadFile () 메소드를 정의하십시오.
uploadFile(file) {
const formData = new FormData();
formData.append('file', file.data);
file.inProgress = true;
this.uploadService.upload(formData).pipe(
map(event => {
switch (event.type) {
case HttpEventType.UploadProgress:
file.progress = Math.round(event.loaded * 100 / event.total);
break;
case HttpEventType.Response:
return event;
}
}),
catchError((error: HttpErrorResponse) => {
file.inProgress = false;
return of(`${file.data.name} upload failed.`);
})).subscribe((event: any) => {
if (typeof (event) === 'object') {
console.log(event.body);
}
});
}
다음으로 여러 이미지 파일을 업로드하는 데 사용할 수있는 uploadFiles () 메소드를 정의하십시오.
private uploadFiles() {
this.fileUpload.nativeElement.value = '';
this.files.forEach(file => {
this.uploadFile(file);
});
}
다음으로 onClick () 메소드를 정의하십시오.
onClick() {
const fileUpload = this.fileUpload.nativeElement;fileUpload.onchange = () => {
for (let index = 0; index < fileUpload.files.length; index++)
{
const file = fileUpload.files[index];
this.files.push({ data: file, inProgress: false, progress: 0});
}
this.uploadFiles();
};
fileUpload.click();
}
다음으로 이미지 업로드 UI의 HTML 템플릿을 만들어야합니다. src / app / home / home.component.html 파일을 열고 다음 내용을 추가하십시오.
<div style="text-align:center; margin-top: 100px; ">
<button mat-button color="warn" (click)="onClick()">
Upload
</button>
<input type="file" #fileUpload id="fileUpload" name="fileUpload" multiple="multiple" accept="image/*" style="display:none;" /></div>
Angular 및 nodejs (express)를 사용한 파일 업로드의 전체 예
HTML 코드
<div class="form-group">
<label for="file">Choose File</label><br/>
<input type="file" id="file" (change)="uploadFile($event.target.files)" multiple>
</div>
TS 구성 요소 코드
uploadFile(files) {
console.log('files', files)
var formData = new FormData();
for(let i =0; i < files.length; i++){
formData.append("files", files[i], files[i]['name']);
}
this.httpService.httpPost('/fileUpload', formData)
.subscribe((response) => {
console.log('response', response)
},
(error) => {
console.log('error in fileupload', error)
})
}
노드 JS 코드
fileUpload API 컨트롤러
function start(req, res) {
fileUploadService.fileUpload(req, res)
.then(fileUploadServiceResponse => {
res.status(200).send(fileUploadServiceResponse)
})
.catch(error => {
res.status(400).send(error)
})
}
module.exports.start = start
multer를 사용하여 서비스 업로드
const multer = require('multer') // import library
const moment = require('moment')
const q = require('q')
const _ = require('underscore')
const fs = require('fs')
const dir = './public'
/** Store file on local folder */
let storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public')
},
filename: function (req, file, cb) {
let date = moment(moment.now()).format('YYYYMMDDHHMMSS')
cb(null, date + '_' + file.originalname.replace(/-/g, '_').replace(/ /g, '_'))
}
})
/** Upload files */
let upload = multer({ storage: storage }).array('files')
/** Exports fileUpload function */
module.exports = {
fileUpload: function (req, res) {
let deferred = q.defer()
/** Create dir if not exist */
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir)
console.log(`\n\n ${dir} dose not exist, hence created \n\n`)
}
upload(req, res, function (err) {
if (req && (_.isEmpty(req.files))) {
deferred.resolve({ status: 200, message: 'File not attached', data: [] })
} else {
if (err) {
deferred.reject({ status: 400, message: 'error', data: err })
} else {
deferred.resolve({
status: 200,
message: 'File attached',
filename: _.pluck(req.files,
'filename'),
data: req.files
})
}
}
})
return deferred.promise
}
}
이 시도
설치
npm install primeng --save
수입
import {FileUploadModule} from 'primeng/primeng';
HTML
<p-fileUpload name="myfile[]" url="./upload.php" multiple="multiple"
accept="image/*" auto="auto"></p-fileUpload>
에서 각도 7/8/9
소스 링크
부트 스트랩 양식 사용
<form>
<div class="form-group">
<fieldset class="form-group">
<label>Upload Logo</label>
{{imageError}}
<div class="custom-file fileInputProfileWrap">
<input type="file" (change)="fileChangeEvent($event)" class="fileInputProfile">
<div class="img-space">
<ng-container *ngIf="isImageSaved; else elseTemplate">
<img [src]="cardImageBase64" />
</ng-container>
<ng-template #elseTemplate>
<img src="./../../assets/placeholder.png" class="img-responsive">
</ng-template>
</div>
</div>
</fieldset>
</div>
<a class="btn btn-danger" (click)="removeImage()" *ngIf="isImageSaved">Remove</a>
</form>
에서 구성 요소 클래스
fileChangeEvent(fileInput: any) {
this.imageError = null;
if (fileInput.target.files && fileInput.target.files[0]) {
// Size Filter Bytes
const max_size = 20971520;
const allowed_types = ['image/png', 'image/jpeg'];
const max_height = 15200;
const max_width = 25600;
if (fileInput.target.files[0].size > max_size) {
this.imageError =
'Maximum size allowed is ' + max_size / 1000 + 'Mb';
return false;
}
if (!_.includes(allowed_types, fileInput.target.files[0].type)) {
this.imageError = 'Only Images are allowed ( JPG | PNG )';
return false;
}
const reader = new FileReader();
reader.onload = (e: any) => {
const image = new Image();
image.src = e.target.result;
image.onload = rs => {
const img_height = rs.currentTarget['height'];
const img_width = rs.currentTarget['width'];
console.log(img_height, img_width);
if (img_height > max_height && img_width > max_width) {
this.imageError =
'Maximum dimentions allowed ' +
max_height +
'*' +
max_width +
'px';
return false;
} else {
const imgBase64Path = e.target.result;
this.cardImageBase64 = imgBase64Path;
this.isImageSaved = true;
// this.previewImagePath = imgBase64Path;
}
};
};
reader.readAsDataURL(fileInput.target.files[0]);
}
}
removeImage() {
this.cardImageBase64 = null;
this.isImageSaved = false;
}
Choose File
btn 업로드를 원하십니까? 두 경우 모두 Bdw는 단순히 FormData를