[사용라이브러리]
javascript lib => html2canvas.js
pdf java lib => pdfbox
[해결방법]
html2canvas를 이용해 scale 옵션을 지정해줘야 함.
[js]
pdf 저장을 위한 스크립트 실행부분
var frm = document.getElementById("pdfFrm");
var fd = new FormData(frm);
var sPageDirection = $("#paperDirection").val();
var sPageSize =$("#paperSize").val();
var oElOuterPreview = $('#outer-preview');
html2canvas(oElOuterPreview.get(0), {
scale: 2 //옵션을 줘야 훨씬 깨끗해짐.
}).then(function (canvas){
var tmpCanvas = document.createElement('canvas');
tmpCanvas.width = canvas.width;
tmpCanvas.height = canvas.height;
var ctx = tmpCanvas.getContext('2d');
ctx.drawImage(canvas,0,0,canvas.width,canvas.height,0,0,canvas.width,canvas.height);
tmpCanvas.toBlob(function(blob) {
if(navigator.msSaveOrOpenBlob || !fd.set){
fd.append("imgFile", blob)
} else {
fd.append("imgFile", blob)
}
fd.append("direction", sPageDirection);
fd.append("size", sPageSize);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200){
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
// this.response is what you're looking for
console.log(this.response, typeof this.response);
if(navigator.msSaveOrOpenBlob){
// ie 전용
navigator.msSaveOrOpenBlob(this.response, filename);
} else {
var a = document.createElement("a");
var url = URL.createObjectURL(this.response)
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
}
}
}
xhr.open('POST', '/saveToPdf.do');
xhr.responseType = 'blob';
xhr.send(fd);
cvs_watermark.hide();
});
})
[java]
넘겨받은 image를 pdf로 저장하는 부분
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
@RequestMapping(value = "/saveToPdf.do", method = RequestMethod.POST)
public void saveToPdf(MultipartHttpServletRequest request, HttpServletResponse response, HttpSession session) throws Exception {
String rootPath = propertyService.getString("Globals.fileStorePath");
long timestamp = System.currentTimeMillis();
SimpleDateFormat dayTime = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
String timeStr = dayTime.format(timestamp);
String page_direction = request.getParameter("paperDirection"); //landscape, a4
String page_size = request.getParameter("paperSize"); //a4, a3
float POINTS_PER_INCH = 72;
float POINTS_PER_MM = 1 / (10 * 2.54f) * POINTS_PER_INCH; //2.834645669291339
//float POINTS_PER_MM = 3.834349419193889f;
try (final PDDocument doc = new PDDocument()){
PDPage page = null;
if(page_size.equalsIgnoreCase("a4")) {
if(page_direction.equalsIgnoreCase("landscape")) {
page = new PDPage(new PDRectangle(297 * POINTS_PER_MM, 210 * POINTS_PER_MM));
}
else {
page = new PDPage(new PDRectangle(210 * POINTS_PER_MM, 297 * POINTS_PER_MM));
}
}
else { //A3
if(page_direction.equalsIgnoreCase("landscape")) {
page = new PDPage(new PDRectangle(420 * POINTS_PER_MM, 297 * POINTS_PER_MM));
}
else {
page = new PDPage(new PDRectangle(297 * POINTS_PER_MM, 420 * POINTS_PER_MM));
}
}
doc.addPage(page);
Iterator<String> itr = request.getFileNames();
List<MultipartFile> mpf = request.getFiles(itr.next().toString());
String contentType = mpf.get(0).getContentType().replace("image/", "");
byte[] imgArr = mpf.get(0).getBytes();
PDImageXObject pdImage = PDImageXObject.createFromByteArray(doc, imgArr, "a");
//현재 설정된 PDF 페이지의 가로/세로 구하기
int pageWidth = Math.round(page.getCropBox().getWidth());
int pageHeight = Math.round(page.getCropBox().getHeight());
//이미지 가로사이즈가 PDF 가로사이즈보다 클 경우를 대비해서 이미지 리사이징 실행
//현재 설정된 PDF 페이지 가로 , 이미지 가로 사이즈로 비율 측정
float imgRatio = 1;
if ( pageWidth < pdImage.getWidth()) {
imgRatio = (float)pdImage.getWidth() / (float)pageWidth;
}
//설정된 비율로 이미지 리사이징
BufferedImage bfImage = pdImage.getImage();
//이미지 sharpen 처리 (효과 없는 듯)
Kernel kernel = new Kernel(3, 3, new float[] { 1f, 1f, 1f, 1f, 2f, 1f, 1f, 1f, 1f });
BufferedImageOp op = new ConvolveOp(kernel);
bfImage = op.filter(bfImage, null);
int imgWidth = Math.round(pdImage.getWidth() / imgRatio);
int imgHeight = Math.round(pdImage.getHeight() / imgRatio);
//이미지를 가운데 정렬하기 위해 좌표 설정
int pageWidthPosition = ((pageWidth - imgWidth) / 2 ) + 10;
int pageHeightPosition = ((pageHeight - imgHeight) / 2);
PDPageContentStream contents = new PDPageContentStream(doc, page);
PDRectangle mediaBox = page.getMediaBox();
contents.drawImage(pdImage, pageWidthPosition, pageHeightPosition, imgWidth, imgHeight);
contents.close();
File f = new File(rootPath+"uploads\\imagePdfTest.pdf");
doc.save(f);
String downloadName = null;
String browser = request.getHeader("User-Agent");
//파일 인코딩
if(browser.contains("MSIE") || browser.contains("Trident") || browser.contains("Chrome")){
//브라우저 확인 파일명 encode
downloadName = URLEncoder.encode(f.getName(), "UTF-8").replaceAll("\\+", "%20");
}else{
downloadName = new String(f.getName().getBytes("UTF-8"), "ISO-8859-1");
}
response.setHeader("Content-Disposition", "attachment; filename=\"" + downloadName +"\"");
response.setContentLength((int)f.length());
response.setContentType("application/octet-stream");
BufferedInputStream in = new BufferedInputStream(
new FileInputStream(f));
FileCopyUtils.copy(in, response.getOutputStream());
in.close();
System.out.println(f.getAbsolutePath());
response.getOutputStream().flush();
response.getOutputStream().close();
} catch (IOException e){
System.err.println("Exception while trying to create pdf document - " + e);
}
}
sqlplus 유용한 명령어 모음 (0) | 2022.05.10 |
---|---|
Apache Log4j 2 보안 업데이트 쉽게하는 방법 (0) | 2021.12.13 |
[OpenLayers] 좌표변환하기 (0) | 2021.10.19 |
[IDE] intellij 에서 외부 jar 추가하는 방법 (0) | 2021.10.08 |
[http] 웹 개발시 유용한 캐시 원터치 삭제 크롬 확장프로그램 (0) | 2021.10.07 |