node.js에서 sharp를 사용해서 이미지 크기 변경하기

web/node.js|2018. 10. 22. 09:27

node.js에서 이미지 크기를 변경하기 위해서 임시 파일에 데이터를 다운로드 받고 파일 크기를 변경하는 작업을 보통 진행한다.


하지만 이번에는 html stream으로 임시로 내려받은 버퍼를 사용해서 사이즈를 변경하고 바로 s3에 전송하거나 파일로 내보내는 작업을 진행해보려한다.


이미지의 사이즈를 변경하기 위해서 필요한 라이브러리는 sharp이다. 

1
npm install sharp
cs

https://www.npmjs.com/package/sharp


먼저 request 요청으로 내려받은 image데이터를 sharp로 이미지를 변경하고 파일로 내보내보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
'use strict';
 
const request = require('request-promise');
const sharp = require('sharp');
const fs = require('fs');
const Stream = require('stream').Transform;
 
class ImageResize {
 
  async imageResize() {
 
    const transformer = sharp().resize(250211);
    const writeStream = fs.createWriteStream('test.jpg');
 
    // fs.writeaStream으로 파일로 쓰기
    await request('https://image.toast.com/aaaaab/ticketlink/TKL_3/ion_main08061242.jpg').pipe(transformer).pipe(writeStream);
 
    // stream 처리를 통해 파일로 직접 쓰기
    this.streamToFile(await request('https://image.toast.com/aaaaab/ticketlink/TKL_3/ion_main08061242.jpg').pipe(transformer));
  }
 
  streamToFile (stream) {
    const chunks = new Stream();
    return new Promise((resolve, reject) => {
      stream.on('data', chunk => chunks.push(chunk));
      stream.on('error', reject);
      stream.on('end', () => fs.writeFileSync('tt.jpg', chunks.read()));
    });
  }
};
 
module.exports = new ImageResize();
cs

코드를 보면 알겠지만 생각보다 간단하다. request 요청으로 받은 html stream을 sharp로 넘겨서 처리하고 그리고 나온 스트림을 writeStream으로 넘겨서 처리하거나 별도의 스트림 처리를 설정해서 파일로 저장할 수 있다.


추가적으로 파일로 내보내는 작업이 아닌 s3로 이미지 파일을 내보내기 위해 이미지 크기가 변경된 stream을 buffer로 바꾸는 작업을 해보자. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
'use strict';
 
const request = require('request-promise');
const sharp = require('sharp');
const fs = require('fs');
const Stream = require('stream').Transform;
 
class ImageResize {
 
  async imageResize() {
 
    const transformer = sharp().resize(250211);
    const writeStream = fs.createWriteStream('test.jpg');
 
    // s3로 전송 (String)
    let dd1 = await this.streamToString(await request('https://image.toast.com/aaaaab/ticketlink/TKL_3/ion_main08061242.jpg').pipe(transformer));
 
    s3.upload({
        Body : ddl 
    });
  }
 
  streamToString (stream) {
    const chunks = [];
    return new Promise((resolve, reject) => {
      stream.on('data', chunk => chunks.push(chunk));
      stream.on('error', reject);
      stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')))
    });
  }
 
};
 
module.exports = new ImageResize();
cs


node.js stream을 이해하면 생각보다 어렵지 않은 작업으로 이미지를 임시로 저장하지 않고 바로 크기를 변경할 수 있다.


소스 git repository

https://github.com/weduls/nodejs_study


참고

https://stackoverflow.com/questions/12740659/downloading-images-with-node-js

https://stackoverflow.com/questions/10623798/writing-node-js-stream-into-a-string-variable

https://stackoverflow.com/questions/13979558/saving-an-image-stored-on-s3-using-node-js


댓글()

div내에 overflow scroll 옵션에 따라 스크롤 생성 시 제일 밑으로 스크롤 내리기

web/javaScript|2018. 6. 17. 20:55

채팅 프로그램을 요새 만들고 있는데 채팅의 경우 스크롤이 새로운 내용이 추가되면 맨 밑으로 이동되어야 한다. 

그래서 jquery를 통해 좀 쉬게 이동하게 할 수 없나 싶어서 찾아보다가 있어서 정리해본다.

const $messageTextBox = $('#messageTextBox');
$messageTextBox.scrollTop($messageTextBox[0].scrollHeight);

div의 태그를 잡아서 해당 스크롤의 높이를 scrollTop 메서드로 잡아주면 자동으로 밑으로 내려가게된다.

 

어려워 어려워.

댓글()

Spring framework에서 html을 pdf만들어 다운로드 하기

web/Spring|2018. 5. 27. 19:50

업무적으로 html 코드를 이용하여 pdf 파일로 내보내기 위해서 자료수집을 많이했다.

하지만 결론부터 이야기하면 원하는대로 다 되지는 않았다.
밑에 이야기 하겠지만 html을 pdf로 만들어주는 라이브러리가 정확하게 html모든 태그를 파싱하지 못할뿐만 아니라, css적용도 정상적으로 되지 않았다. 



그래도 다시해본 결과!!!!! ( 이 글 쓰고나서 더 조사해본 결과.. 포기하지 마시길 )

=> html2pdf를 사용하면 거의 대부분의 css를 적용할 수있다.



1. pom.xml 설정 
itextpdf -> pdf를 생성하기 위해 필요한 라이브러리
xmlworker -> xml 파싱을 위해 필요한 라이브러리
html2pdf -> itext의 7버전을 사용하기 위해 필요한 라이브러리


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13</version>
</dependency>
        
<!-- https://mvnrepository.com/artifact/com.itextpdf.tool/xmlworker -->
<dependency>
    <groupId>com.itextpdf.tool</groupId>
    <artifactId>xmlworker</artifactId>
    <version>5.5.13</version>
</dependency>
            
<!-- https://mvnrepository.com/artifact/com.itextpdf/html2pdf -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>html2pdf</artifactId>
    <version>2.0.2</version>
</dependency>
cs



2. view 관련 설정
BeanNameViewResolver 설정은 뷰 이름과 동일한 이름을 가진 빈을 뷰 클래스로 사용한다.
ex) 만약 pdfview라는 view를 컨트롤러에서 호출 할 시 해당요청에 대한 view는 pdfview 클래스에 처리



1
2
3
<beans:bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
    <beans:property name="order" value="0" />
</beans:bean>
cs




3. AbstractView 클래스 설정
기존의 Spring에서 제공하는 AbstractPdfView 클래스를 이용하여 pdf view를 사용할 수 있으나, 해당 클래스는 com.itext라이브러리가 아닌 com.lowagie만을 사용할 수 있다. 

 두 개의 라이브러리는 서로 같지만 com.lowagie 라이브러리는 com.itext의  2.1.7버전과 동일하고 더이상 지원이 멈추어서 새로 제공되는 기능을 사용할 수 없다. 그렇기 때문에 이 문제를 해결하기 위해서 AbstractView를 상속하여 com.itext 라이브러리를 사용할 수 있는 클래스를 재정의 해야한다. 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.wedul.pdf;
 
import java.io.ByteArrayOutputStream;
import java.util.Map;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.web.servlet.view.AbstractView;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
 
public abstract class AbstractITextPdfView extends AbstractView {
 
public AbstractITextPdfView() {
    setContentType("application/pdf");
}
 
@Override
protected boolean generatesDownloadContent() {
    return true;
}
 
@Override
protected final void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception  {
 
    // IE workaround: write into byte array first.
    ByteArrayOutputStream baos = createTemporaryOutputStream();
 
    // Apply preferences and build metadata.
    Document document = new Document(PageSize.A4.rotate(), 36365436);
    PdfWriter writer = PdfWriter.getInstance(document, baos);
    prepareWriter(model, writer, request);
    buildPdfMetadata(model, document, request);
 
    // Build PDF document.
    document.open();
    buildPdfDocument(model, document, writer, request, response);
    document.close();
 
    // Flush to HTTP response.
    response.setHeader("Content-Disposition""attachment");    // make browser to ask for download/display
    writeToResponse(response, baos);
}
 
protected void prepareWriter(Map<String, Object> model, PdfWriter writer, HttpServletRequest request) throws DocumentException {
    writer.setViewerPreferences(getViewerPreferences());
}
 
protected int getViewerPreferences() {
    return PdfWriter.ALLOW_PRINTING | PdfWriter.PageLayoutSinglePage;
}
 
 
protected void buildPdfMetadata(Map<String, Object> model, Document document, HttpServletRequest request) {
}
 
 
protected abstract void buildPdfDocument(Map<String, Object> model, Document document, PdfWriter writer,
                                         HttpServletRequest request, HttpServletResponse response) throws Exception;
}
cs



그리고 기본적으로 폰트가 한글을 지원하지 않기때문에 한글지원을 위해서 폰트를 제공해 주어야한다. 이를 위해서 사용하는 fontprovider 클래스를 구현해야한다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.wedul.pdf;
 
import java.io.IOException;
 
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactoryImp;
import com.itextpdf.text.pdf.BaseFont;
 
class DefaultFontProvider extends FontFactoryImp {
 private String _default;
 public DefaultFontProvider(String def) {
  _default = def;
 }
 
 // I believe this is the correct override, but there are quite a few others.
 public Font getFont(String fontname,String encoding, boolean embedded, float size,int style, BaseColor color) {
  try {
   //한글 깨짐을 방지 하기위한 폰트 세팅
   return new Font(BaseFont.createFont(_default, BaseFont.IDENTITY_H, BaseFont.EMBEDDED), 9, style, BaseColor.BLACK);
  } catch (DocumentException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return null;
 }
 
}
cs




3. Controller 


1
2
3
4
5
6
@RequestMapping(value = "/download/pdf", method = RequestMethod.GET)
public ModelAndView downloadPdf() {
    ModelAndView modelAndView = new ModelAndView("pdfView""fileName""test.pdf");
    return modelAndView;
}
 
cs




4. PdfView 클래스
실질적인 pdf 파일을 만드는 클래스이다. pdf를 만드는 라이브러리는 버전 별로 사용하는 방법이 다르다.

1.) 2.x 버전
HTMLWorker를 사용하여 만들수 있다. 하지만 아주 기초적인 태그에 대해서 지원해주고 css지원이 적으나 심플하게 pdf를 만들 수 있기 때문에 가장 많이 사용 되는 버전이다.

2.) 5.x 버전
XMLWorker와 XMLParser를 통해서 pdf를 만들수있다. 하지만 여기서 문제가 발생했는데, 단순하게 XMLParser 클래스에서 parse 메소드를 통해서 pdf를 만들수있지만 div 태그가 포함될경우 만들어지지 않는다. 또 XMLWorkerHelper 클래스를 통해서 각각 Element를 사용할 경우 css가 적용이 되지 않는다. (삽질을 하게 만들었다 아주 맘에 안들었다...)

3.) 7.x
HtmlConverter 클래스를 통해서 변경할 수 있지만 이것을 spring에서 사용하기에는 좀 부적절 했다.

-> Spring에서 ModelAndView를 사용해서 pdf를 만들지 않고 라이브러리에서 제공하는 방식으로 하면 가장 좋게 만들어진다.

모든 버전에 대한 코드를 적어보았다..



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import java.io.FileInputStream;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.util.Map;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.stereotype.Component;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.ElementList;
import com.itextpdf.tool.xml.XMLWorker;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.itextpdf.tool.xml.css.CssFile;
import com.itextpdf.tool.xml.css.StyleAttrCSSResolver;
import com.itextpdf.tool.xml.html.CssAppliers;
import com.itextpdf.tool.xml.html.CssAppliersImpl;
import com.itextpdf.tool.xml.html.Tags;
import com.itextpdf.tool.xml.parser.XMLParser;
import com.itextpdf.tool.xml.pipeline.css.CSSResolver;
import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
import com.itextpdf.tool.xml.pipeline.end.ElementHandlerPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
 
@Component
public class PDFView extends AbstractITextPdfView {
 
    @SuppressWarnings({ "static-access""deprecation""unchecked" })
    protected void buildPdfDocument(Map<String, Object> model, Document document, PdfWriter writer,
            HttpServletRequest request, HttpServletResponse response) throws Exception {
        
        // version 7        
//        PdfWriter writer2 = PdfWriter.getInstance(document, response.getOutputStream());
//        String fileName = String.valueOf(model.get("fileName"));
//         
//        // 파일 다운로드 설정
//        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\";");
//        response.setHeader("Content-Transfer-Encoding", "binary");
//        response.setContentType("application/pdf");
//        
//        document.open();
//        XMLWorkerHelper helper = XMLWorkerHelper.getInstance();
//
//        // 폰트 설정에서 별칭으로 줬던 "MalgunGothic"을 html 안에 폰트로 지정한다.
//        String htmlStr = "<html><head><body style='font-family: MalgunGothic;'>"
//                    + "<p>PDF 안에 들어갈 내용입니다.</p>"
//                    + "<div><h3>한글, English, 漢字.</h3></div>"
//                + "</body></head></html>";
//         
//        HtmlConverter.convertToPdf(htmlStr, response.getOutputStream(), null);
        
        
        // version 5
        // PdfWriter 생성
        PdfWriter.getInstance(document, response.getOutputStream());
        String fileName = String.valueOf(model.get("fileName"));
         
        // 파일 다운로드 설정
        response.setHeader("Content-Disposition""attachment; filename=\"" + fileName + "\";");
        response.setHeader("Content-Transfer-Encoding""binary");
        response.setContentType("application/pdf");
         
        // Document 오픈
        document.open();
        
        // CSS
        CSSResolver cssResolver = new StyleAttrCSSResolver();
        CssFile cssFile = XMLWorkerHelper.getInstance().getCSS(new FileInputStream(PDFView.class.getClassLoader().getResource("pdf.css").getPath()));
        cssResolver.addCss(cssFile);
             
        // HTML, 폰트 설정
        XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
        fontProvider.register(PDFView.class.getClassLoader().getResource("malgun.ttf").getPath(), "MalgunGothic"); // MalgunGothic은 alias,
        CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
         
        HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
        htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
         
        // Pipelines
        ElementList elements = new ElementList();
        ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
        HtmlPipeline html = new HtmlPipeline(htmlContext, end);
        CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
        
        String htmlStr0 = "<html><head><body style='font-family: MalgunGothic;'>"
                + "<p>PDF 안에sdf 들어갈 내용입니다.</p>"
                + "<div style='text-align:center; font-size:30px;'; ><h3>한글sdf, English, 漢字.</h3></div>"
                + "</body></head></html>";
        
        XMLWorker worker = new XMLWorker(css, true);
        XMLParser xmlParser = new XMLParser(worker, Charset.forName("UTF-8"));
        
        for (int i =0 ; i <= 1 ; i++) {
            // 폰트 설정에서 별칭으로 줬던 "MalgunGothic"을 html 안에 폰트로 지정한다.
            StringReader strReader;
            
            strReader = new StringReader(htmlStr0);
            xmlParser.parse(strReader);
            
            PdfPTable table = new PdfPTable(1);
            PdfPCell cell = new PdfPCell();
            
            for (Element element : elements) {
                cell.addElement(element);
            }
            table.addCell(cell);
            document.add(table);
            document.newPage();
        }
        
        document.close();
        writer.close();
 
// version 2                
//        String fileName = String.valueOf(model.get("fileName"));
//        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\";");
//        response.setHeader("Content-Transfer-Encoding", "binary");
//        response.setContentType("application/pdf");
//        
//        StyleSheet css = new StyleSheet();
//        css.loadTagStyle(HtmlTags.H1, "color", "red");
//        
//        HTMLWorker htmlWorker = new HTMLWorker(document);
//        HashMap<String, Object> interfaceProps = new HashMap<String, Object>();
//        
//        DefaultFontProvider dfp = new DefaultFontProvider(PDFView.class.getClassLoader().getResource("malgun.ttf").getPath());
//        interfaceProps.put(HTMLWorker.FONT_PROVIDER, dfp);
//
//        StringReader reader = null; 
//        PdfWriter.getInstance(document, response.getOutputStream());
//        document.open();
//        
//        reader = new StringReader(
//                  new
//                  StringBuffer("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">")
//                  .append("<html xmlns=\"http://www.w3.org/1999/xhtml\"><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /></head><body>").append("<h1>").append("test").
//                  append("</h1>")
//                  .append("테스트 입니다").append("</body></html>").toString());
//        
//        List<Element> objects = htmlWorker.parseToList(reader, css, interfaceProps);
//        for (int k = 0; k < objects.size(); ++k) {
//            document.add((Element) objects.get(k));
//        }
//            
//        document.close();
    }
}
cs


삽질의 결론은 스프링에서 Pdf ModelAndView를 사용할 때는 2.x 버전의 HTMLWorker를 쓰기로 하였고 단순 pdf파일을 만들때는 7.x 버전을 사용하기로 하였다.



몇가지 삽질 하면서 찾은 고생하신 분들의 출처 사이트도 적어본다.


출처
버전 2
http://zero-gravity.tistory.com/251

버전 5
http://kooremo.tistory.com/m/entry/itext이용해서-pdf파일-만드는-샘플-소스

XMLParser 사용시 div가 포함된 html이 생성되지 않는다고 고민하는 사람의 주소
http://itext.2136553.n4.nabble.com/Problems-with-the-font-tags-and-div-tags-in-xml-worker-td4657646.html






소스 풀버전은 내 github 페이지에서 확인할 수 있다.
https://github.com/weduls/pdfdown_example

댓글()
  1. 제발 2018.11.06 10:55 댓글주소  수정/삭제  댓글쓰기

    2번 view 관련설정을 springboot gradle project 에서 하려면 어떻게 설정해줘야 하나요
    광고는 클릭 했습니다. (찡긋)

    • wedul 2018.11.06 11:01 댓글주소  수정/삭제

      광고 클릭 감사합니다.
      gradle 프로젝트 여부와 상관없이 글에서 2번은 xml로 bean을 생성해 준것이기 때문에 저대로 하셔도 됩니다. 만약 자바로 configuration으로 bean을 생성해주고 싶을때는 이 소스를 참고하시면 될거에요 https://github.com/weduls/pdfdown_example/blob/master/src/main/java/com/wedul/pdf/Conf.java

      위에 git 주소에 샘플 코드가 들어있으니 한번 확인해보세요~

    • 제발 2018.11.06 16:01 댓글주소  수정/삭제

      2버전은 이미지가 안들어가고

      5버젼은 inline으로 css 줘도 에러나고

      7버전은 한글 안나오는거 맞나요?

      제가 잘 못하고 있는건지 원래 그런건지 모르겠어서 여쭤 봅니다. ㅜㅜ

    • wedul 2018.11.06 16:35 댓글주소  수정/삭제

      개발을한지 좀 되어서 기억이 가물가물하지만 정리하면 2번은 간단한기능만 심플하게 가능했고 5번은 div와 같은 특정 태그가 제공되지 않았습니다.

      이 글에는 없지만 git에 있는 코드를 보면 7버전을 사용하여 한글화 까지 진행한 코드가 있을 겁니다.

      아마 제발님도 7버전을 사용하시면 원하시는대로 pdf를 만드실 수 있을 것 같습니다.

      아무쪼록 성공하시길 바랍니다.

  2. 덕덕 2018.11.20 15:49 댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 초보개발자입니다. 제가 bootstrap에서 제공되는 summernote의 code(css와 html이 모두 들어있는)를 ajax로 넘겨서 pdf로 똑같이 출력하고 싶은데요. Spring을 사용하다보니 이해가 안가는 부분이 있어서 질문드려요. ajax에서 넘긴 정보(정보까진 가져왔습니다 controller로)를 어떻게 pdfview로 가져가서 셋팅하고 파일을 생성하는지 궁금합니다.

    • Favicon of https://wedul.site BlogIcon 위들 wedul 2018.11.20 16:38 신고 댓글주소  수정/삭제

      네 안녕하세요. 위에 올려놓고 git에도 올려놓은방식대로 AbstractITextPdfView을 상속잗아 구현한 pdfView 컴포넌트를 만드시고 그 후 컨트롤러에서 받은 html코드를 해당 view로 넘겨서 라이브러리 버전중 편하신 방식대로 처리하시면 될 것 같습니다.

      위에 있는 코드만 사실 복붙하셔도 잘될거에요

    • 덕덕 2018.11.20 19:56 댓글주소  수정/삭제

      여기서 사용되고 있는 css와 폰트 설정을 안쓰고 부트스트랩에서 제공하는걸 쓰려면 그 경로로 설정해줘야 하나요?
      제 css 경로가 ${pageContext.request.contextPath}/resources/css/vertical-layout-light/style.css" 인데 계속 널포인트가 뜨네요 ㅠ..

    • Favicon of https://wedul.site BlogIcon 위들 wedul 2018.11.21 01:07 신고 댓글주소  수정/삭제

      spring 자체에 이해가 조금 더 필요할 것 같습니다. 제가 더 설명하고 싶지만 덕덕님에 소스를 보지 못하는 상태에서는 많이 어렵네요.

      쉽게 설명하자면 pdfView를 하나 만들고 그 부분에서 라이브러리를 사용해서 html소스와 css를 넣어주고 해서 다운로드 가능하게 해준다.

      위에 부분이 실 로직에 전부입니다. 파일을 잘 가지고 오셔서 다시한번 시도해보세요. 건승을 빌겠습니다!!!

  3. 덕덕 2018.11.21 10:53 댓글주소  수정/삭제  댓글쓰기

    다시 한번 질문해서 죄송합니다. 에러 없이 모든 코드가 실행되는데 따로 다운로드 창이 따로 나오지 않습니다. 뭐가 문제일까요??

  4. 닉넴 2018.12.17 10:28 댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 먼저 좋은 글 남겨주셔서 감사합니다.
    그런데 혹시 itext 에서는 <input type='text' id='aa' name='aa' vlaue='abcd'> 이렇게 value값을 absolute 를 이용해서
    원하는 위치에 찍어낼 방법은 없을까요??

  5. hans 2019.01.08 13:56 댓글주소  수정/삭제  댓글쓰기

    개발중 막막해서 질문남깁니다..
    추상클래스내 prepareWriter 메소드는 어디에 존재하는 메소드인가요? 에러가나서 컴파일되지않는데..

  6. 초보개발 2019.03.07 15:00 댓글주소  수정/삭제  댓글쓰기

    안녕하세요! 스프링공부하는 학생입니다. pdf 2버전을 사용하면 태그가 적용이안되고 7버전을 사용하면 한글이 안되던데 한글 적용시키는 방법이 혹시 있을까요???
    fontprovider는 만들었습니다

  7. 감사합니다 2019.03.22 10:03 댓글주소  수정/삭제  댓글쓰기

    먼저 너무나 감사드립니다.

    작성해주신 게시물 보고 현재 만들고 있는 휴가신청서 양식을 거의 다 만들었습니다.
    마지막 하나만 해결하면 되는데요 ..

    밑에 이름이 있고 서명하는 '(인)' 부분에 서명 이미지 파일을 img 태그에 박아서 z-index 로
    '(인)' 위에다가 서명 이미지 파일이 박혀있는 <img> 겹치게 배치하고 싶은데요.. 이게 잘 안되네요 ..
    p태그인 '(인)'에 background-image 를 줘도 안먹더라구요 ...

    이게 해결이 잘 안되고 있어서 완성을 못하고 있습니다 ㅎㅎㅎㅎㅎ

    일단 버전은 현재 게시물에 있는 버전으로 개발을 했습니다.

    위 댓글에 '아마 제발님도 7버전을 사용하시면 원하시는대로 pdf를 만드실 수 있을 것 같습니다.'
    라고 하셨는데요. 7버전에서는 위 같은 문제를 해결할 수 있으려나요..
    7버전 소스를 넣었는데 계속 에러가 나서 ... 아직 적용을 못해봤습니다 ...

    현재 게시물에 있는 버전으로는 z-index를 통해서 태그끼리 겹치기는 불가능한 걸까요 ??

    • Favicon of https://wedul.site BlogIcon 위들 wedul 2019.03.22 10:45 신고 댓글주소  수정/삭제

      해당 라이브러리가 태그랑 css가 조금 제한되기 때문에 조금 답답한 부분이 있습니다. 계속 테스트 해보셔야 할거같아요 ㅠ 그리고 7버전이 그나마 가장 많이 호환되는거 같으니 잘 적용해보시면 도움이 되실거에여.

      저도 이걸 적용해 본적이 오래되어 크게 도움은 못드려서 죄송합니다 ㅠ

    • 감사합니다 2019.03.22 10:52 댓글주소  수정/삭제

      ㅎㅎㅎ 아닙니다 위들님 덕분에 만들 수 있었는걸요
      7버전 적용이 시급한데 .. 에러 해결에 힘써야겠군요 ㅎㅎㅎ
      답변 감사드려요 ^^

      좋은 하루 되세요 ^^

  8. 감사합니다 2019.03.22 10:51 댓글주소  수정/삭제  댓글쓰기

    ㅎㅎㅎ 아닙니다 위들님 덕분에 만들 수 있었는걸요
    7버전 적용이 시급한데 .. 에러 해결에 힘써야겠군요 ㅎㅎㅎ
    답변 감사드려요 ^^

  9. 핵초보 2019.04.11 20:40 댓글주소  수정/삭제  댓글쓰기

    안녕하세요! 스프링 공부하고 있는 학생입니다.!!
    jsp 페이지에서 폼 작성 후 버튼을 누르면 pdf 파일이 생성되고 다시 홈페이지에 보이게 만들고 싶은데 ,
    일단 jsp의 html 태그들을 Controller 로 보내질 못하고 있습니다..
    jsp 의 html 태그를 그대로 PDFview.java 로 보내는지
    아니면 jsp 의 데이터들을 PDFview.java 에 미리 만들어 놓은 html 폼에 적용 시켜주는지 궁금합니다.!!
    만약 jsp에서 html 태그를 그대로 PDFview.java 로 보낸다면 어떻게 해야하는지 궁금합니다!!!

    • Favicon of https://wedul.site BlogIcon 위들 wedul 2019.04.12 10:28 신고 댓글주소  수정/삭제

      jsp폼에서 작성한 내용으로 만들고 싶으시면 컨트롤러에서 데이터를 받아서 modelAndView에서 PdfView호출시 값을 넘겨서 html코드를 대신해서 사용하시면 해결되실거에요

  10. 초보개발자 2019.04.19 09:48 댓글주소  수정/삭제  댓글쓰기

    안녕하세요! 좋은 소스덕분에 pdf출력을 쉽게 할수있었습니다!ㅎㅎ
    pdf출력시 테두리가 생기던데
    어떤 이유에 의해서 생기는건지 알수있을까요??

  11. 뼝아리 2019.05.29 16:50 댓글주소  수정/삭제  댓글쓰기

    안녕하세요 : ) 덕분에 재밌게 적용해보고 있습니다.
    감사합니다~

    buildPdfMetadata메서드는 무슨 역할을 하는 것인지 여쭤봐도 될까요?

    • Favicon of https://wedul.site BlogIcon 위들 wedul 2019.05.29 20:21 신고 댓글주소  수정/삭제

      안녕하세요! 저는 사용하지 않지만 AbstractITextPdfView를 상속받아 사용할때 필요에 따라서 medtdata 수정하는 부분을 재정의해서 사용하는 곳 같아요.

spring boot 재시작 없이 frontend(html, js..) 변경내용 사용하기

web/Spring|2018. 5. 27. 19:31

spring boot를 공부하면서 html요소가 자동으로 변경되지 않아서.. 
계속 껏다켜야해서 너무 불편했다.

그래서 구글링 하던중 방법을 알게되어 적어본다.

1. pom.xml 추가


1
2
3
4
5
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>
cs


2. debug 모드로 실행

3. eclipse 설정 중 Build Automatically 설정 여부 확인 (기본으로 사용으로 설정되어 있음)


댓글()

css 파일 Uncaught SyntaxError: Invalid or unexpected token 에러

web/Web|2018. 5. 27. 10:53

css 파일 로드시 


브라우저에서 다음과 같은 오류가 출력되는 경우가 있다.


Uncaught SyntaxError: Invalid or unexpected token



이 때 가장 의심해 볼 수 있는 부분은 css 파일 로드시


<script src=""> 

다음과 같은 방식으로 로드했는지 의심해 보아야 한다.


css 파일은 자바스크립트 파일이 아니기 때문에 로드시 문법 오류를 유발 할 수 있다. 


그래서 css 파일로드시 다음과 같이 로드하여야 한다.


<link href=""  rel="stylesheet" type="text/css" /> 

댓글()
  1. 2019.08.21 14:23 댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

JSP 개념 설명

web/Web|2016. 12. 22. 12:04

JSP

 JSP(Java Server Page) 서블릿이라고 하는 자바  프로그래밍 기법에 기반을 두고 있으며PHP ASS 같이HTML 함께 스크립트를 사용할  있도록 되어있다.

-> JSP 자바 서블릿 기반의 서버 스크립트 기술  하나이며서블릿의 특징을 대부분 가지고 있다.

->JSP 장점은  서블릿의 장점과 일맥상통한데프로세스 기반이 아니라 스레드 기반으로 실행 된다는 것이다프로세스는 하나만 만들어지고 동일한 요청은 스레드를 만들어서 처리하기 때문에 시스템 자원을 절약하고효율적인 공유가 가능해진다.

-> 자바를 기반으로 하는 강력한 객체지향 언어의 뒷바침으로써 자바의 모든기능을 쓸수 있는 자점이 있다.

 

JSP 특징

->빈즈(Beans)라고 하는 자바 컴포넌트를 사용할  있다.

->최초 서블릿으로 컴파일된 후에 메로리에서 처리되기 때문에 많은 사용자가 접속도 원할히   있다.

->JSP 또는 다른 서블릿간의 데이터 공유가 쉽다.(page, request, session, application, scope)

-> 자바의 모든 기능을 사용   있다.

 

JSP 동작원리

기존 html 동작

 기존의 HTML 사용할  사용자가 특정 도메인 주소로 접속을 시도 하면DNS 서버에서 IP주소를 반환 받아해당 포트로 접속을 시도하고 DocumentRoot 설정된 디렉토리에서 index.html파일을 읽는다.

 

JSP 구성과 흐름도

  1. 특정 도메인 주소로 접속을 시도하고 IP 받은 , 80포트로 접속을 시도한다.
  2.   서버는 요청내용을 분석하고서블릿 컨테이너에게 요청을 넘긴다.
  3. 그리고 서블릿 컨테이너에서 JSP 파일에 해당하는 서블릿이 있는지 확인하고없을 경우 JSP 파일을 서블릿으로 컴파일한다컴파일된 JSP 서블릿으로 변환되어 컨테이너에 적재된다.
  4. 서블릿 내용  데이터베이스 처리 부분이 있으면데이터베이스에서 데이터를 가져온다.
  5. 화면에 보일 내용을 정리해서 HTML 문서 형태로 클라이언트에  전송한다.
  6. 웹브라우저는  서버에서 보낸 텍스트 내용  HTML 태그를 분석해서 적절히 변환하여 화면에 보여준다


'web > Web' 카테고리의 다른 글

Get과 Post 방식의 차이점 설명  (0) 2016.12.22
자바 빈즈 개념 설명(Java Beans)  (0) 2016.12.22
JSP 개념 설명  (0) 2016.12.22
아파치와 톰캣의 차이  (0) 2016.12.22
jsp 기본 문법 설명  (0) 2016.12.22
JSP 2.0에서의 문자셋 지정 방식  (0) 2016.12.22

태그 : html, jsp, Spring, Web

댓글()

jsp 기본 문법 설명

web/Web|2016. 12. 22. 12:03

주석

JSP에서 주석 처리 방법

<!-- -->

 

JSP 주석 : 클라이언트로 전달 되지 않는 주석

<%-- 주석 --%>

 

지시어

지시어는 해당하는 JSP 파일의 속성을 기술하는 곳으로, JSP 컨테이너에게 해당 페이지를 어떻게 처리해야 하는지 전달하기 위한 내용을 담고 있다.

크게 page, include, taglib으로 나뉘며 각각의 속성이 있다.

  1. Page 지시어

Page 지시어는 현재의 JSP 페이지를 컨테이너에서 처리하는  필요한 각종 속성을 기술하는 부분으로 대개 소스 코드  앞에서   있다.

문법)

<%@ page 속성="속성값1" 속성2="속성값2" %>

 

Ex)

<%@ page contextType="text/html;charset=euc-kr" import="javax.sql.*", java.util.*"  errorPage="error.jsp" %>

 

Page 들어가는 대표 속성 

 import : jsp 내에서 사용할 외부 자바 패키지나 클래스의 import 지정

Session : 세션의 사용유무(기본값 : true)

Buffer : 버퍼의 크기 (기본값 : 8kb)

autoFlush : 버퍼의 내용 자동 비움 (기본값 : true)

isThreadSafe 단일 스레드 모델을 사용함으로써 동시성 제어 여부 지정(기본값 : true)

Info : JSP 페이지에 대한 설명

errorPage :  현재 페이지 내에서 오류 발생  호출될 페이지 지정

isErrorPage 오류만을 처리하는 페이지로 지정(기본값 : false)

contextType : MIME 형식 지정  캐릭터  지정 (기본값 :  text/html:charset=ISO-8859-1)

Extends : 현재 JSP 페이지를 특정 클래스를 상속한 클래스로 지정

 

  1. Include 지시어

Include 지시어는 현재 JSP 파일에 다른 HTML이나 JSP 문서를 포함하기 위한 기능을 제공한다.

Include 지시어는 여러 페이지에 공통으로 들어가는 내용을 관리할  매우 유용하다.

<%@ include file="xxx.jsp" />

-> 그러나 성능적인 측면에서는 그다지 권장할 만한 기법은 아니다.

 

  1. Taglib 지시어

Taglib 지시어는 JSP 기능의 확장을 위해 만들어진 사용자 정의 태그를 JSP 파일에서 사용하기 위해 태그 라이브러리와 관련된 정보를 기술하는 목적

 

액션

  1. Include

Include 지시어와 비슷하나 include 지시어는 해당 파일을 포함시킨 다음 컴파일 하는데 비해, include 액션은 실행 시점에서 해당 파일을 호출 하여 포함한다는 차이가 있다.

Ex)

Include_action.jsp

<jsp:include page="footer.jsp">

<jsp:param name="email" value="test@test.net" />

<jsp:param name="tel" value="000-000-0000" />

</jsp:include>

 

Footer.jsp

<%= request.getParameter("email") %>

<%= request.getParameter("tel") %>

-> 호출 뿐만 아니라 파라미터도 전달   있다.

 

  1. Forward

Forward액션은 include 액션과 유사하지만 현재 페이지를 완전히 다른 페이지로 전환할  사용한다.

Include 제어권을 다른 jsp파일로 넘겼다가 다시 가져오지만, forward 제어권을 완전히 넘겨버린다.

<jsp:forward page="footer.jsp">

<jsp:param name="email" value="test@test.net" />

<jsp:param name="tel" value="000-000-0000" />

-> 동일하게 파라미터 또한 전달   있다.

 

  1. useBean 액션

액션에서 가장 중요한 부분이다.

<jsp:useBean id="변수명" class="빈즈 클래스명" />

<jsp:setProperty name="변수명" property="속성명" />

<jsp:getProperty name="변수명" property="속성명" />

->jsp에서 빈즈 사용  경우 setProperty getProperty 빈즈 클래스의 getter setter 메소드를 내부적으로 호출한다.

useBean id : 빈즈 클래스의 인스턴스명으로 사용할 변수

             class : 빈즈 클래스의 클래스명으로패키지 경로를 포함.

setProperty name : 빈즈 클래스의 인스턴스명으로 id 값에 설정했던 변수명

Property : 속성 값으로 빈즈 클래스의 setXX 메서드와 매칭될 속성 . * 지정하면 모든 setter 자동으로 매칭됨

        

선언과 표현식

  1. 선언

JSP내에 메서드나 멤버변수 선언.

<%!

//멤버변수 선언이나 메서드 선언이   있다.

String str = "test";

Public boolean check() }{

 

]

%>

 

  1. 표현식

표현식은  <%= %> 사용해서 간단한 데이터 출력이나 메서드 호출 등에 이용한다코드 마지막에  세미콜론을 붙혀주어야한다.

<%= result %>

 

  1. 스크립트 릿

스크립트 릿은 JSP 문자내에 자바 코드를 기술 하는 부분이다.

어디서나 자바문법을 사용할  있는 장점이 있으나 근래는 JSP 내에서 가급적 스크립트릿을 사용하지 말것을 권장한다 이유는

JSP 내에 복잡한 프로그램 로직이 많이 들어가게 되면 유지보수가 어려워지고자바코드를 이해할  없는 그래픽 디자이너 등과  작업에 어려움이

있을  있다.

-> 그래서 JSTL 이용한 커스텀 태그 라이브러리나, JSP 빈즈 사용을 권장한다.

<%

// 로컬 변수 선언이나 간단한 로직 사용

String str = "text";

%>

 

 

<%

For(int i=1l i<=10; i++) {

%>

<%= I %><br>

<%

}

%>

 

HTML 자바문법을 같이 사용할  있지만 이렇게 남용할 경우 버그 우려가 높고 가독성이 떨이지기에 JSP 빈즈를 사용한다.

 

JSP 내장 객체

JSP 내장 객체는 JSP 내에서 선언하지 않고 사용하는 객체이다.

  1. Request

Javax.servlet.http.HttpServletRequest 클래스이다.

주로 HTML 폼을 통해 전달되는 값을 가져올  사용한다.

 

  1. Response

Javax.servlet.http.HttpServletResponse 객체에 대한 참조 변수다.

사용자 요청애 대한 응답을 처리하기 위해 사용된다. Request 비해 많이 사용되는 메서드는 적은 편이다.

 

  1. Session

Javax.servlet.http.HttpSession 인터페이스의 참조 변수다.

세션은 해당  서비스에 접속한 사용자의 정보를 서버에 보관할  사용한다.

'web > Web' 카테고리의 다른 글

Get과 Post 방식의 차이점 설명  (0) 2016.12.22
자바 빈즈 개념 설명(Java Beans)  (0) 2016.12.22
JSP 개념 설명  (0) 2016.12.22
아파치와 톰캣의 차이  (0) 2016.12.22
jsp 기본 문법 설명  (0) 2016.12.22
JSP 2.0에서의 문자셋 지정 방식  (0) 2016.12.22

태그 : html, jsp, Spring, Web

댓글()