pdf 다운로드 수정
parent
d38244b1b3
commit
d52ea88613
@ -1,5 +1,803 @@
|
||||
package cokr.xit.base.file.pdf;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.font.PDType0Font;
|
||||
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
|
||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||
import org.apache.pdfbox.pdmodel.graphics.state.RenderingMode;
|
||||
import org.egovframe.rte.fdl.string.EgovStringUtil;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import cokr.xit.fims.cmmn.CmmnUtil;
|
||||
import cokr.xit.fims.cmmn.Print;
|
||||
import cokr.xit.fims.cmmn.pdf.PDFColors;
|
||||
import cokr.xit.fims.cmmn.pdf.PDFCoordinate;
|
||||
import cokr.xit.fims.cmmn.pdf.Pstn;
|
||||
import cokr.xit.fims.cmmn.pdf.PstnAndSize;
|
||||
import cokr.xit.fims.cmmn.pdf.Size;
|
||||
import cokr.xit.fims.cmmn.pdf.print.DefaultOtptArtclStng;
|
||||
import cokr.xit.fims.cmmn.pdf.print.format.PDFPrintFormat;
|
||||
import cokr.xit.fims.sprt.MediaUtil;
|
||||
import cokr.xit.fims.sprt.PrintOption;
|
||||
import cokr.xit.foundation.data.DataObject;
|
||||
|
||||
public class PDFWriter {
|
||||
protected String paper;
|
||||
protected Print print;
|
||||
protected PDFPrintFormat format;
|
||||
|
||||
protected DataObject otptBscStng;
|
||||
protected List<DataObject> otptArtclStngList;
|
||||
|
||||
protected float[] paperMilimeter = new float[2];
|
||||
|
||||
public void setPaper(String paperType) {
|
||||
this.paper = paperType;
|
||||
if(paperType.equals("01")) {
|
||||
this.paperMilimeter = new float[] {210.0f , 297.0f};
|
||||
} else if(paperType.equals("02")){
|
||||
this.paperMilimeter = new float[] {216.0f , 279.0f};
|
||||
}
|
||||
}
|
||||
|
||||
public void setFormat(PDFPrintFormat format) {
|
||||
this.format = format;
|
||||
};
|
||||
public void setPrint(Print print) {
|
||||
this.print = print;
|
||||
};
|
||||
|
||||
|
||||
public void setOtptBscStng(DataObject otptBscStng) {
|
||||
this.otptBscStng = otptBscStng;
|
||||
};
|
||||
public void setOtptArtclStngList(List<DataObject> otptArtclStngList) {
|
||||
this.otptArtclStngList = otptArtclStngList;
|
||||
};
|
||||
public Map<String, Object> makePdfFile(String formatType, String formatName, PrintOption printOption, List<DataObject> dataObjectList) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
String resultFilePath = this.filePathForNewFile();
|
||||
PDDocument doc = new PDDocument();//pdf문서 생성
|
||||
|
||||
//폰트 로드
|
||||
Map<String, PDType0Font> fontMap = this.getFontMap(doc);
|
||||
|
||||
//용지 크기 설정
|
||||
PDRectangle paper = null;
|
||||
if(this.paper.equals("01")) {
|
||||
paper = PDRectangle.A4;
|
||||
} else {
|
||||
paper = PDRectangle.LETTER;
|
||||
}
|
||||
|
||||
|
||||
List<DefaultOtptArtclStng> prototypeStngList = this.format.getPrototypeStngs();
|
||||
|
||||
try {
|
||||
|
||||
|
||||
//출력요소별 속성 정보 추가
|
||||
this.format.appendOtptAttribute(this.otptArtclStngList);
|
||||
|
||||
//출력 요소 정렬
|
||||
Comparator<DataObject> comparator1 = (item1, item2) -> {
|
||||
int int1 = item1.string("UNIQUE_YN").equals("Y") ? 0 : 1;
|
||||
int int2 = item2.string("UNIQUE_YN").equals("Y") ? 0 : 1;
|
||||
return Integer.compare(int1, int2);
|
||||
};
|
||||
Comparator<DataObject> comparator2 = (item1, item2) -> {
|
||||
int int1 = item1.number("OTPT_ARTCL_ORDR").intValue();
|
||||
int int2 = item2.number("OTPT_ARTCL_ORDR").intValue();
|
||||
return Integer.compare(int1, int2);
|
||||
};
|
||||
otptArtclStngList = otptArtclStngList.stream()
|
||||
.sorted(comparator1.thenComparing(comparator2)).collect(Collectors.toList());
|
||||
|
||||
|
||||
//대표단속사진 설정 여부 확인
|
||||
boolean rprsCrdnPhotoYn = false;
|
||||
if(otptArtclStngList.stream().filter(item -> item.string("OTPT_ARTCL_NM").equals("rprsCrdnPhoto")).count() > 0) {
|
||||
rprsCrdnPhotoYn = true;
|
||||
}
|
||||
|
||||
for(DataObject dataObject : dataObjectList) {
|
||||
//페이지생성(건별)
|
||||
PDPage blankPage = new PDPage(paper);
|
||||
doc.addPage(blankPage);
|
||||
|
||||
// 작업 페이지 설정
|
||||
PDPage page = doc.getPage(doc.getNumberOfPages()-1);
|
||||
// 컨텐츠 스트림 열기
|
||||
PDPageContentStream contentStream = new PDPageContentStream(doc, page);
|
||||
|
||||
boolean completeFoldLine = false;
|
||||
|
||||
for(DataObject otptArtclStng : otptArtclStngList) {
|
||||
String otptArtclNm = otptArtclStng.string("OTPT_ARTCL_NM");
|
||||
|
||||
if(!otptArtclNm.equals("background") && !completeFoldLine) {
|
||||
//접는곳 점선 그리기
|
||||
if(!otptBscStng.string("FOLD_LINE_PSTN_SE_CD").equals("")) {
|
||||
this.renderFoldLine(contentStream, paper, otptBscStng.string("FOLD_LINE_PSTN_SE_CD"));
|
||||
}
|
||||
completeFoldLine = true;
|
||||
}
|
||||
|
||||
DefaultOtptArtclStng prototypeStng = prototypeStngList.stream()
|
||||
.filter(item -> item.getOtptArtclNm().equals(otptArtclNm)).toList().get(0);
|
||||
|
||||
float[] pstn = this.getPstnStng(prototypeStng, otptArtclStng, this.paper);
|
||||
float[] size = this.getSize(prototypeStng, otptArtclStng);
|
||||
|
||||
boolean forPost = prototypeStng.isForPost();
|
||||
String defaultValue = prototypeStng.getOtptBscVl();
|
||||
|
||||
if(prototypeStng.getComponentType().equals("text")) {
|
||||
String align = this.getAlign(prototypeStng, otptArtclStng);
|
||||
String lineChgYn = this.getLineChgYn(prototypeStng, otptArtclStng);
|
||||
PDType0Font font = this.getFontType(prototypeStng, otptArtclStng, fontMap);
|
||||
int fontSz = this.getFontSize(prototypeStng, otptArtclStng);
|
||||
RenderingMode fontStyle = this.getFontStyle(prototypeStng, otptArtclStng);
|
||||
PDColor fontColor = this.getFontColor(prototypeStng, otptArtclStng);
|
||||
|
||||
String textValue = this.format.getMappingValue(otptArtclNm,defaultValue,forPost,dataObject,printOption,print);
|
||||
|
||||
this.writeText(contentStream, textValue, pstn, size[0], align, lineChgYn
|
||||
, font, fontSz, fontStyle, fontColor);
|
||||
|
||||
} else if(prototypeStng.getComponentType().equals("image")) {
|
||||
|
||||
String imagePath = this.format.getMappingValue(otptArtclNm,defaultValue,forPost,dataObject,printOption,print);
|
||||
|
||||
if(EgovStringUtil.null2void(imagePath).equals("")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!imagePath.startsWith("files")) {
|
||||
imagePath = CmmnUtil.copyStaticResource(imagePath, false);
|
||||
}
|
||||
|
||||
File imageFile = new File(imagePath);
|
||||
InputStream is = new FileInputStream(imageFile);
|
||||
|
||||
String imageKey = "";
|
||||
List<DataObject> mosSet = null;
|
||||
if(otptArtclNm.equals("rprsCrdnPhoto")) {
|
||||
imageKey = this.format.getMappingValue(otptArtclNm+"Key",defaultValue,forPost,dataObject,printOption,print);
|
||||
mosSet = this.format.getMosSet(imageKey, dataObject);
|
||||
}
|
||||
this.insertImage(doc, contentStream, is, pstn, size);
|
||||
|
||||
if(otptArtclNm.equals("rprsCrdnPhoto") && !imageKey.equals("") && mosSet != null) {
|
||||
|
||||
File imageFile0 = new File(imagePath);
|
||||
InputStream is0 = new FileInputStream(imageFile0);
|
||||
|
||||
List<PstnAndSize> transformedMosaicInfos = MediaUtil.getTransformedMosaic(
|
||||
mosSet, is0, new PstnAndSize(pstn[0],pstn[1], size[0], size[1])
|
||||
);
|
||||
|
||||
for(int k=0; k < transformedMosaicInfos.size(); k++) {
|
||||
PstnAndSize mosaicInfo = transformedMosaicInfos.get(k);
|
||||
|
||||
InputStream blackImageStream = new ClassPathResource("samplefiles/black.png").getInputStream();
|
||||
this.insertImage(doc, contentStream, blackImageStream,
|
||||
mosaicInfo.getPstn().to2Float(), mosaicInfo.getSize().to2Float());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
} else if(prototypeStng.getComponentType().equals("images")) {
|
||||
|
||||
List<String> imagePaths = this.format.getMappingValues(otptArtclNm,defaultValue,forPost,dataObject,printOption,print);
|
||||
|
||||
List<String> imageKeys = new ArrayList<String>();
|
||||
List<List<DataObject>> mosSets = new ArrayList<List<DataObject>>();
|
||||
if(otptArtclNm.equals("crdnPhoto")) {
|
||||
imageKeys = this.format.getMappingValues(otptArtclNm+"Key",defaultValue,forPost,dataObject,printOption,print);
|
||||
if(rprsCrdnPhotoYn && imagePaths.size() > 0) {
|
||||
imageKeys.remove(0);
|
||||
}
|
||||
for(String imageKey : imageKeys) {
|
||||
mosSets.add(this.format.getMosSet(imageKey, dataObject));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(otptArtclNm.equals("crdnPhoto")) {
|
||||
if(rprsCrdnPhotoYn && imagePaths.size() > 0) {
|
||||
imagePaths.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
int printCntSetting = otptBscStng.number("OTPT_PHOTO_CNT").intValue();
|
||||
int dataImageCnt = imagePaths.size();
|
||||
|
||||
if(printCntSetting != 0 && dataImageCnt != 0) {
|
||||
|
||||
List<PstnAndSize> devideInfos = this.devideImageArea(pstn, size, printCntSetting, dataImageCnt);
|
||||
|
||||
for (int i=0; i< devideInfos.size(); i++){
|
||||
PstnAndSize devideInfo = devideInfos.get(i);
|
||||
|
||||
if(EgovStringUtil.null2void(imagePaths.get(i)).equals("")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!imagePaths.get(i).startsWith("files")) {
|
||||
imagePaths.set(i, CmmnUtil.copyStaticResource(imagePaths.get(i), false));
|
||||
}
|
||||
|
||||
String imagePath = imagePaths.get(i);
|
||||
|
||||
File imageFile = new File(imagePath);
|
||||
InputStream is = new FileInputStream(imageFile);
|
||||
|
||||
this.insertImage(doc, contentStream, is,
|
||||
devideInfo.getPstn().to2Float(), devideInfo.getSize().to2Float());
|
||||
|
||||
|
||||
if(otptArtclNm.equals("crdnPhoto") && !imageKeys.isEmpty() && !mosSets.isEmpty()) {
|
||||
|
||||
if(mosSets.get(i) != null) {
|
||||
String imagePath0 = imagePaths.get(i);
|
||||
|
||||
File imageFile0 = new File(imagePath0);
|
||||
InputStream is0 = new FileInputStream(imageFile0);
|
||||
|
||||
List<PstnAndSize> transformedMosaicInfos = MediaUtil.getTransformedMosaic(
|
||||
mosSets.get(i), is0, devideInfo
|
||||
);
|
||||
|
||||
for(int k=0; k < transformedMosaicInfos.size(); k++) {
|
||||
PstnAndSize mosaicInfo = transformedMosaicInfos.get(k);
|
||||
InputStream blackImageStream = new ClassPathResource("samplefiles/black.png").getInputStream();
|
||||
this.insertImage(doc, contentStream, blackImageStream,
|
||||
mosaicInfo.getPstn().to2Float(), mosaicInfo.getSize().to2Float());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}//출력항목 loop 끝
|
||||
|
||||
if(!completeFoldLine) {
|
||||
if(!otptBscStng.string("FOLD_LINE_PSTN_SE_CD").equals("")) {
|
||||
this.renderFoldLine(contentStream, paper, otptBscStng.string("FOLD_LINE_PSTN_SE_CD"));
|
||||
}
|
||||
}
|
||||
|
||||
contentStream.close();
|
||||
|
||||
} //출력자료건수 loop 끝
|
||||
|
||||
|
||||
doc.save(resultFilePath);
|
||||
doc.close();
|
||||
|
||||
String downloadFileName = print.getFormatKorName()+"_"+print.getPrintRequestDt()+".pdf";
|
||||
result.put("filename", downloadFileName);
|
||||
result.put("filePath", resultFilePath);
|
||||
result.put("file", new File(resultFilePath));
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("출력오류."+e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public String filePathForNewFile() {
|
||||
|
||||
SimpleDateFormat ymdhmsFormat = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
String currentTime = ymdhmsFormat.format(new Date());
|
||||
String year = currentTime.substring(0, 4);
|
||||
String month = currentTime.substring(4, 6);
|
||||
String day = currentTime.substring(6, 8);
|
||||
|
||||
String fileResultRootPath = "files" + File.separator + "result" + File.separator + "print";
|
||||
|
||||
String fileResultFolderPath = fileResultRootPath
|
||||
+ File.separator + year + File.separator + month + File.separator + day;
|
||||
File formatFileResultFolder = new File(fileResultFolderPath);
|
||||
if(!formatFileResultFolder.exists()) {
|
||||
formatFileResultFolder.mkdirs();
|
||||
}
|
||||
String resultPdfPath = fileResultFolderPath
|
||||
+ File.separator + currentTime + "_" + (print.getFileNameIndex()) + ".pdf";
|
||||
|
||||
print.setFileNameIndex(print.getFileNameIndex()+1);
|
||||
|
||||
return resultPdfPath;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* mm단위로 입력된 값을 pdf좌표계 형식으로 변환한다.
|
||||
*/
|
||||
public PDFCoordinate toPDFCoordinate(float[] XYmm) {
|
||||
float Xmm = XYmm[0];
|
||||
float Ymm = XYmm[1];
|
||||
|
||||
float Xpt = Print.mmToPt(Xmm);
|
||||
float Ypt = Print.mmToPt(Ymm);
|
||||
|
||||
float YptMax = Print.mmToPt(this.paperMilimeter[1]);
|
||||
|
||||
return new PDFCoordinate(Xpt, Ypt, YptMax);
|
||||
}
|
||||
|
||||
/**
|
||||
* 텍스트를 pdf에 입력한다.
|
||||
*/
|
||||
public void writeText(PDPageContentStream contentStream, String allText,
|
||||
float[] XYmm, float textAreaWidth_mm, String align, String newLineYn,
|
||||
PDType0Font font, int fontSize, RenderingMode fontStyle, PDColor fontColor) {
|
||||
try {
|
||||
if(allText == null) {
|
||||
allText = "";
|
||||
}
|
||||
if(newLineYn == null || newLineYn.equals("")) {
|
||||
newLineYn = "N";
|
||||
}
|
||||
|
||||
float[] xyAbsolute = this.toPDFCoordinate(XYmm).absolute();
|
||||
|
||||
float textAreaWidth_pt = Print.mmToPt(textAreaWidth_mm);
|
||||
|
||||
float allTextWidth = calcTextWidth(font, fontSize, allText);
|
||||
|
||||
String textArr[];
|
||||
if(allText.equals("") || allText.length() == 1 || textAreaWidth_pt == 0
|
||||
|| (allTextWidth <= textAreaWidth_pt)
|
||||
|| newLineYn.equals("N")) {
|
||||
|
||||
textArr = new String[] { allText };
|
||||
|
||||
} else {
|
||||
|
||||
textArr = splitByLineForLargeText(font, fontSize, allText, textAreaWidth_pt);
|
||||
|
||||
}
|
||||
|
||||
String firstLine = textArr[0];
|
||||
float firstLineWidth = calcTextWidth(font, fontSize, firstLine);
|
||||
|
||||
contentStream.beginText();
|
||||
contentStream.setFont(font, fontSize);
|
||||
contentStream.setRenderingMode(fontStyle);
|
||||
contentStream.setNonStrokingColor(fontColor);
|
||||
|
||||
float resultY = xyAbsolute[1] - fontSize;
|
||||
|
||||
float firstLineAlignCorrection = 0;
|
||||
if(align.equals("right")) {
|
||||
firstLineAlignCorrection = textAreaWidth_pt - firstLineWidth;
|
||||
} else if(align.equals("center")) {
|
||||
firstLineAlignCorrection = (textAreaWidth_pt - firstLineWidth)/2.0f;
|
||||
}
|
||||
|
||||
float resultX = xyAbsolute[0] + firstLineAlignCorrection;
|
||||
|
||||
contentStream.newLineAtOffset(resultX, resultY);
|
||||
contentStream.showText(textArr[0]);
|
||||
|
||||
if(textArr.length > 1) {
|
||||
float beforeLineWidth = firstLineWidth;
|
||||
|
||||
for(int i = 1; i < textArr.length; i++) {
|
||||
String thisLine = textArr[i];
|
||||
float thisLineWidth = this.calcTextWidth(font, fontSize, thisLine);
|
||||
float alignCorrection = 0;
|
||||
|
||||
if(align.equals("right")) {
|
||||
alignCorrection = beforeLineWidth - thisLineWidth;
|
||||
} if(align.equals("center")) {
|
||||
alignCorrection = (beforeLineWidth - thisLineWidth)/2.0f;
|
||||
}
|
||||
|
||||
contentStream.newLineAtOffset(alignCorrection, -(fontSize + 1));
|
||||
contentStream.showText(thisLine);
|
||||
|
||||
beforeLineWidth = thisLineWidth;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
contentStream.endText();
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("PDF 파일 출력 중 오류가 발생하였습니다."+e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 글꼴모양,폰트크기 등에 따른 텍스트의 가로 길이(pt)를 계산한다.
|
||||
*/
|
||||
public float calcTextWidth(PDType0Font font, int fontSize, String text) {
|
||||
try {
|
||||
return (font.getStringWidth(text) / 1000.0f) * fontSize;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("PDF 파일 출력 중 오류가 발생하였습니다.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 출력할 텍스트가 지정한 영역 안에 들어가지 않을 경우 줄바꿈 처리를 위해 텍스트를 나누어 배열로 반환한다.
|
||||
*/
|
||||
public String[] splitByLineForLargeText(PDType0Font font, int fontSize, String allText, float textAreaWidth_pt) {
|
||||
|
||||
float allTextWidth = calcTextWidth(font, fontSize, allText);
|
||||
|
||||
if(allText.equals("") || allText.length() == 1 || textAreaWidth_pt == 0
|
||||
|| (allTextWidth <= textAreaWidth_pt)
|
||||
) {
|
||||
return new String[] { allText };
|
||||
}
|
||||
|
||||
ArrayList<String> textList = new ArrayList<String>();
|
||||
|
||||
while(!allText.equals("")) {
|
||||
int lengthForLine = this.getLengthForLine(font, fontSize, allText, textAreaWidth_pt);
|
||||
String newLine = allText.substring(0,lengthForLine);
|
||||
textList.add(newLine);
|
||||
allText = allText.substring(lengthForLine);
|
||||
}
|
||||
|
||||
return textList.toArray(new String[textList.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 텍스트를 줄바꿈 처리할 경우 첫 라인에 출력될 글자 수를 반환한다.
|
||||
*/
|
||||
private int getLengthForLine(PDType0Font font, int fontSize, String allText, float textAreaWidth_pt) {
|
||||
int forLine = allText.length();
|
||||
if(forLine <= 1) {
|
||||
return forLine;
|
||||
};
|
||||
|
||||
for( ; ; forLine--) {
|
||||
if(forLine == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
boolean hit = ( this.calcTextWidth(font, fontSize, allText.substring(0, forLine)) <= textAreaWidth_pt );
|
||||
if(hit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return forLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* pdf에 이미지를 삽입한다.
|
||||
*/
|
||||
public void insertImage(PDDocument doc, PDPageContentStream contentStream, InputStream imageStream, float[] XYmm,
|
||||
float[] SIZEmm) {
|
||||
|
||||
float[] xyAbsolute = this.toPDFCoordinate(XYmm).absolute();
|
||||
|
||||
float[] size = new float[] {
|
||||
Print.mmToPt(SIZEmm[0]),Print.mmToPt(SIZEmm[1])
|
||||
};
|
||||
try {
|
||||
|
||||
PDImageXObject image = PDImageXObject.createFromByteArray(doc, imageStream.readAllBytes(), "temp");
|
||||
contentStream.drawImage(image, xyAbsolute[0], xyAbsolute[1]-size[1], size[0], size[1]);
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("PDF 파일 출력 중 오류가 발생하였습니다."+e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<PstnAndSize> devideImageArea(float[] totAreaPstn, float[] totAreaSize, int imageCntSetting, int dataImageCnt) {
|
||||
List<PstnAndSize> result = new ArrayList<PstnAndSize>();
|
||||
|
||||
int printable = imageCntSetting <= dataImageCnt ? imageCntSetting : dataImageCnt;
|
||||
|
||||
if(printable <= 1) {
|
||||
result.add(new PstnAndSize(totAreaPstn[0], totAreaPstn[1], totAreaSize[0], totAreaSize[1]));
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean longerThenWidth = totAreaSize[1] > totAreaSize[0];
|
||||
|
||||
int xLengthOfD2 = 0;
|
||||
int yLengthOfD2 = 0;
|
||||
|
||||
if(printable == 2){
|
||||
if(longerThenWidth) {
|
||||
xLengthOfD2 = 1;
|
||||
yLengthOfD2 = 2;
|
||||
} else {
|
||||
xLengthOfD2 = 2;
|
||||
yLengthOfD2 = 1;
|
||||
}
|
||||
} else if(printable == 3 || printable == 4){
|
||||
xLengthOfD2 = 2;
|
||||
yLengthOfD2 = 2;
|
||||
} else if(printable == 5 || printable == 6){
|
||||
if(longerThenWidth) {
|
||||
xLengthOfD2 = 2;
|
||||
yLengthOfD2 = 3;
|
||||
} else {
|
||||
xLengthOfD2 = 3;
|
||||
yLengthOfD2 = 2;
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("PDF 파일 출력 중 오류가 발생하였습니다.");
|
||||
}
|
||||
|
||||
PstnAndSize[][] d2Array = new PstnAndSize[xLengthOfD2][yLengthOfD2];
|
||||
Size cellSize = new Size(totAreaSize[0] / (xLengthOfD2 * 1.0f), totAreaSize[1] / (yLengthOfD2 * 1.0f));
|
||||
|
||||
d2Array[0][0] = new PstnAndSize(totAreaPstn[0], totAreaPstn[1], cellSize.getWidth(), cellSize.getHeight());
|
||||
d2Array = this.fillImageCells(d2Array);
|
||||
|
||||
//출력영역 크기 병합
|
||||
if(printable == 3 || printable == 5) {
|
||||
|
||||
boolean longerThenWidth_cell = cellSize.getHeight() > cellSize.getWidth();
|
||||
if(longerThenWidth_cell) {
|
||||
d2Array = this.mergeLastImageCell(d2Array, "left");
|
||||
} else {
|
||||
d2Array = this.mergeLastImageCell(d2Array, "up");
|
||||
}
|
||||
|
||||
}
|
||||
for(int y=0; y < yLengthOfD2; y++) {
|
||||
for(int x=0; x < xLengthOfD2; x++) {
|
||||
if(d2Array[x][y] != null) {
|
||||
result.add(d2Array[x][y]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private PstnAndSize[][] fillImageCells(PstnAndSize[][] d2) {
|
||||
int xLengthOfD2 = d2.length;
|
||||
int yLengthOfD2 = d2[0].length;
|
||||
|
||||
PstnAndSize firstCell = d2[0][0];
|
||||
|
||||
Size cellSize = firstCell.getSize();
|
||||
float cellWidth = cellSize.getWidth();
|
||||
float cellHeight = cellSize.getHeight();
|
||||
|
||||
Pstn startPoint = firstCell.getPstn();
|
||||
float spX = startPoint.getLeft();
|
||||
float spY = startPoint.getTop();
|
||||
|
||||
for(int x=0; x < xLengthOfD2; x++) {
|
||||
for(int y=0; y < yLengthOfD2; y++) {
|
||||
if(x != 0 || y != 0) {
|
||||
d2[x][y] = new PstnAndSize(spX + (cellWidth * (x * 1.0f)), spY + (cellHeight * (y * 1.0f)), cellSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return d2;
|
||||
}
|
||||
|
||||
public PstnAndSize[][] mergeLastImageCell(PstnAndSize[][] d2, String mergeDirection) {
|
||||
if(!mergeDirection.equals("up") && !mergeDirection.equals("left")) {
|
||||
throw new RuntimeException("PDF 파일 출력 중 오류가 발생하였습니다.");
|
||||
}
|
||||
|
||||
int xLengthOfD2 = d2.length;
|
||||
int yLengthOfD2 = d2[0].length;
|
||||
|
||||
int lastCellIndexX = xLengthOfD2-1;
|
||||
int lastCellIndexY = yLengthOfD2-1;
|
||||
|
||||
int mergeTargetCellIndexX = 0;
|
||||
int mergeTargetCellIndexY = 0;
|
||||
|
||||
if(mergeDirection.equals("up")) {
|
||||
mergeTargetCellIndexX = lastCellIndexX;
|
||||
mergeTargetCellIndexY = lastCellIndexY-1;
|
||||
}
|
||||
if(mergeDirection.equals("left")) {
|
||||
mergeTargetCellIndexX = lastCellIndexX-1;
|
||||
mergeTargetCellIndexY = lastCellIndexY;
|
||||
}
|
||||
|
||||
//병합대상셀
|
||||
if(mergeDirection.equals("up")) {
|
||||
d2[mergeTargetCellIndexX][mergeTargetCellIndexY] = (d2[mergeTargetCellIndexX][mergeTargetCellIndexY]).x2Height();
|
||||
}
|
||||
if(mergeDirection.equals("left")) {
|
||||
d2[mergeTargetCellIndexX][mergeTargetCellIndexY] = (d2[mergeTargetCellIndexX][mergeTargetCellIndexY]).x2Width();
|
||||
}
|
||||
|
||||
//마지막셀
|
||||
d2[lastCellIndexX][lastCellIndexY] = null;
|
||||
|
||||
return d2;
|
||||
}
|
||||
|
||||
/**
|
||||
* pdf에 봉합선을 넣는다.
|
||||
*/
|
||||
public void renderFoldLine(PDPageContentStream contentStream, PDRectangle paper, String foldCode) {
|
||||
if(foldCode.equals("") && !foldCode.equals("01") && !foldCode.equals("02")) {
|
||||
return;
|
||||
}
|
||||
|
||||
float paperWidth = paper.getWidth();
|
||||
|
||||
float partHeight;
|
||||
if(foldCode.equals("01")) {
|
||||
if(paper.A4.equals(paper)) {
|
||||
partHeight = 99;
|
||||
} else {
|
||||
partHeight = 93;
|
||||
}
|
||||
} else {
|
||||
partHeight = 93;
|
||||
}
|
||||
|
||||
float margin = 0;
|
||||
if(foldCode.equals("02")) {
|
||||
margin = 18;
|
||||
}
|
||||
|
||||
float bottomFold = margin + partHeight; //하단접는곳
|
||||
float topFold = margin + (partHeight * 2); //상단접는곳
|
||||
|
||||
float bottomFold_pt = Print.mmToPt(bottomFold);
|
||||
float topFold_pt = Print.mmToPt(topFold);
|
||||
|
||||
try {
|
||||
contentStream.setLineDashPattern(new float[]{3,1}, 0);
|
||||
contentStream.moveTo(0, topFold_pt);
|
||||
contentStream.lineTo(paperWidth, topFold_pt);
|
||||
contentStream.stroke();
|
||||
contentStream.moveTo(0, bottomFold_pt);
|
||||
contentStream.lineTo(paperWidth, bottomFold_pt);
|
||||
contentStream.stroke();
|
||||
contentStream.setLineDashPattern(new float[]{}, 0);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("PDF 파일 출력 중 오류가 발생하였습니다."+e);
|
||||
}
|
||||
}
|
||||
|
||||
public float[] getPstnStng(DefaultOtptArtclStng prototypeStng, DataObject sggStng, String paperSeCd) {
|
||||
if(!sggStng.string("LEFT_PSTN").equals("") && !sggStng.string("TOP_PSTN").equals("")) {
|
||||
return new float[] {
|
||||
sggStng.number("LEFT_PSTN").floatValue(),
|
||||
sggStng.number("TOP_PSTN").floatValue()
|
||||
};
|
||||
} else {
|
||||
return new float[] {
|
||||
prototypeStng.getLeftPstn(paperSeCd),
|
||||
prototypeStng.getTopPstn(paperSeCd)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public PDType0Font getFontType(DefaultOtptArtclStng prototypeStng, DataObject sggStng, Map<String, PDType0Font> fontMap) {
|
||||
if(sggStng != null && !sggStng.isEmpty() && !sggStng.string("FONT_NM").equals("")) {
|
||||
return fontMap.get(sggStng.string("FONT_NM"));
|
||||
} else {
|
||||
return fontMap.get(prototypeStng.getFontNm());
|
||||
}
|
||||
}
|
||||
|
||||
public int getFontSize(DefaultOtptArtclStng prototypeStng, DataObject sggStng) {
|
||||
if(!sggStng.string("FONT_SZ").equals("")) {
|
||||
return sggStng.number("FONT_SZ").intValue();
|
||||
} else {
|
||||
return prototypeStng.getFontSz();
|
||||
}
|
||||
}
|
||||
|
||||
public RenderingMode getFontStyle(DefaultOtptArtclStng prototypeStng, DataObject sggStng) {
|
||||
if(!sggStng.string("FONT_STYLE").equals("")) {
|
||||
return RenderingMode.valueOf(sggStng.string("FONT_STYLE"));
|
||||
} else {
|
||||
return RenderingMode.valueOf(prototypeStng.getFontStyle());
|
||||
}
|
||||
}
|
||||
|
||||
public PDColor getFontColor(DefaultOtptArtclStng prototypeStng, DataObject sggStng) {
|
||||
if(!sggStng.string("FONT_COLOR").equals("")) {
|
||||
return PDFColors.getColor(sggStng.string("FONT_COLOR"));
|
||||
} else {
|
||||
return PDFColors.getColor(prototypeStng.getFontColor());
|
||||
}
|
||||
}
|
||||
|
||||
public float[] getSize(DefaultOtptArtclStng prototypeStng, DataObject sggStng) {
|
||||
if(!sggStng.string("WIDTH_SZ").equals("")) {
|
||||
return new float[] {
|
||||
sggStng.number("WIDTH_SZ").floatValue(),
|
||||
sggStng.number("HEIGHT_SZ").floatValue()
|
||||
};
|
||||
} else {
|
||||
return new float[] {
|
||||
prototypeStng.getWidthSz(),
|
||||
prototypeStng.getHeightSz()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public String getAlign(DefaultOtptArtclStng prototypeStng, DataObject sggStng) {
|
||||
if(!sggStng.string("TEXT_SORT").equals("")) {
|
||||
return sggStng.string("TEXT_SORT");
|
||||
} else {
|
||||
return prototypeStng.getTextSort();
|
||||
}
|
||||
}
|
||||
|
||||
public String getLineChgYn(DefaultOtptArtclStng prototypeStng, DataObject sggStng) {
|
||||
if(!sggStng.string("LINE_CHG_YN").equals("")) {
|
||||
return sggStng.string("LINE_CHG_YN");
|
||||
} else {
|
||||
return prototypeStng.getLineChgYn();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, PDType0Font> getFontMap(PDDocument doc) {
|
||||
try {
|
||||
Map<String, PDType0Font> fontMap = Map.of(
|
||||
"notokrBold", PDType0Font.load(doc, new ClassPathResource("fonts/notokr-bold.ttf").getInputStream()),
|
||||
"gulim", PDType0Font.load(doc, new ClassPathResource("fonts/gulim.ttf").getInputStream()),
|
||||
"gulimche", PDType0Font.load(doc, new ClassPathResource("fonts/gulimche.ttf").getInputStream()),
|
||||
"batang", PDType0Font.load(doc, new ClassPathResource("fonts/batang.ttf").getInputStream()),
|
||||
"batangche", PDType0Font.load(doc, new ClassPathResource("fonts/batangche.ttf").getInputStream()),
|
||||
"dotum", PDType0Font.load(doc, new ClassPathResource("fonts/dotum.ttf").getInputStream()),
|
||||
"dotumche", PDType0Font.load(doc, new ClassPathResource("fonts/dotumche.ttf").getInputStream()),
|
||||
"gungsuh", PDType0Font.load(doc, new ClassPathResource("fonts/gungsuh.ttf").getInputStream()),
|
||||
"gungsuhche", PDType0Font.load(doc, new ClassPathResource("fonts/gungsuhche.ttf").getInputStream())
|
||||
);
|
||||
return fontMap;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("글꼴 로드 오류"+e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,518 +1,11 @@
|
||||
package cokr.xit.fims.cmmn.pdf.print;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||
import org.apache.pdfbox.pdmodel.font.PDType0Font;
|
||||
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
|
||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||
import org.apache.pdfbox.pdmodel.graphics.state.RenderingMode;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import cokr.xit.fims.cmmn.Print;
|
||||
import cokr.xit.fims.cmmn.pdf.PDFColors;
|
||||
import cokr.xit.fims.cmmn.pdf.PDFCoordinate;
|
||||
import cokr.xit.fims.cmmn.pdf.Pstn;
|
||||
import cokr.xit.fims.cmmn.pdf.PstnAndSize;
|
||||
import cokr.xit.fims.cmmn.pdf.Size;
|
||||
import cokr.xit.foundation.data.DataObject;
|
||||
|
||||
public class PDFPrintUtil extends Print {
|
||||
|
||||
private float[] paperMilimeter = new float[2];
|
||||
|
||||
public void setting(String paperType) {
|
||||
if(paperType.equals("01")) {
|
||||
this.paperMilimeter = new float[] {210.0f , 297.0f};
|
||||
} else if(paperType.equals("02")){
|
||||
this.paperMilimeter = new float[] {216.0f , 279.0f};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String filePathForNewFile() {
|
||||
|
||||
SimpleDateFormat ymdhmsFormat = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
String currentTime = ymdhmsFormat.format(new Date());
|
||||
String year = currentTime.substring(0, 4);
|
||||
String month = currentTime.substring(4, 6);
|
||||
String day = currentTime.substring(6, 8);
|
||||
|
||||
String fileResultRootPath = "files" + File.separator + "result" + File.separator + "print";
|
||||
|
||||
String fileResultFolderPath = fileResultRootPath
|
||||
+ File.separator + year + File.separator + month + File.separator + day;
|
||||
File formatFileResultFolder = new File(fileResultFolderPath);
|
||||
if(!formatFileResultFolder.exists()) {
|
||||
formatFileResultFolder.mkdirs();
|
||||
}
|
||||
String resultPdfPath = fileResultFolderPath
|
||||
+ File.separator + currentTime + "_" + (this.fileNameIndex++) + ".pdf";
|
||||
|
||||
return resultPdfPath;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* mm단위로 입력된 값을 pdf좌표계 형식으로 변환한다.
|
||||
*/
|
||||
public PDFCoordinate toPDFCoordinate(float[] XYmm) {
|
||||
float Xmm = XYmm[0];
|
||||
float Ymm = XYmm[1];
|
||||
|
||||
float Xpt = mmToPt(Xmm);
|
||||
float Ypt = mmToPt(Ymm);
|
||||
|
||||
float YptMax = mmToPt(this.paperMilimeter[1]);
|
||||
|
||||
return new PDFCoordinate(Xpt, Ypt, YptMax);
|
||||
}
|
||||
|
||||
/**
|
||||
* 텍스트를 pdf에 입력한다.
|
||||
*/
|
||||
public void writeText(PDPageContentStream contentStream, String allText,
|
||||
float[] XYmm, float textAreaWidth_mm, String align, String newLineYn,
|
||||
PDType0Font font, int fontSize, RenderingMode fontStyle, PDColor fontColor) {
|
||||
try {
|
||||
if(allText == null) {
|
||||
allText = "";
|
||||
}
|
||||
if(newLineYn == null || newLineYn.equals("")) {
|
||||
newLineYn = "N";
|
||||
}
|
||||
|
||||
float[] xyAbsolute = this.toPDFCoordinate(XYmm).absolute();
|
||||
|
||||
float textAreaWidth_pt = mmToPt(textAreaWidth_mm);
|
||||
|
||||
float allTextWidth = calcTextWidth(font, fontSize, allText);
|
||||
|
||||
String textArr[];
|
||||
if(allText.equals("") || allText.length() == 1 || textAreaWidth_pt == 0
|
||||
|| (allTextWidth <= textAreaWidth_pt)
|
||||
|| newLineYn.equals("N")) {
|
||||
|
||||
textArr = new String[] { allText };
|
||||
|
||||
} else {
|
||||
|
||||
textArr = splitByLineForLargeText(font, fontSize, allText, textAreaWidth_pt);
|
||||
|
||||
}
|
||||
|
||||
String firstLine = textArr[0];
|
||||
float firstLineWidth = calcTextWidth(font, fontSize, firstLine);
|
||||
|
||||
contentStream.beginText();
|
||||
contentStream.setFont(font, fontSize);
|
||||
contentStream.setRenderingMode(fontStyle);
|
||||
contentStream.setNonStrokingColor(fontColor);
|
||||
|
||||
float resultY = xyAbsolute[1] - fontSize;
|
||||
|
||||
float firstLineAlignCorrection = 0;
|
||||
if(align.equals("right")) {
|
||||
firstLineAlignCorrection = textAreaWidth_pt - firstLineWidth;
|
||||
} else if(align.equals("center")) {
|
||||
firstLineAlignCorrection = (textAreaWidth_pt - firstLineWidth)/2.0f;
|
||||
}
|
||||
|
||||
float resultX = xyAbsolute[0] + firstLineAlignCorrection;
|
||||
|
||||
contentStream.newLineAtOffset(resultX, resultY);
|
||||
contentStream.showText(textArr[0]);
|
||||
|
||||
if(textArr.length > 1) {
|
||||
float beforeLineWidth = firstLineWidth;
|
||||
|
||||
for(int i = 1; i < textArr.length; i++) {
|
||||
String thisLine = textArr[i];
|
||||
float thisLineWidth = this.calcTextWidth(font, fontSize, thisLine);
|
||||
float alignCorrection = 0;
|
||||
|
||||
if(align.equals("right")) {
|
||||
alignCorrection = beforeLineWidth - thisLineWidth;
|
||||
} if(align.equals("center")) {
|
||||
alignCorrection = (beforeLineWidth - thisLineWidth)/2.0f;
|
||||
}
|
||||
|
||||
contentStream.newLineAtOffset(alignCorrection, -(fontSize + 1));
|
||||
contentStream.showText(thisLine);
|
||||
|
||||
beforeLineWidth = thisLineWidth;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
contentStream.endText();
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("PDF 파일 출력 중 오류가 발생하였습니다."+e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 글꼴모양,폰트크기 등에 따른 텍스트의 가로 길이(pt)를 계산한다.
|
||||
*/
|
||||
public float calcTextWidth(PDType0Font font, int fontSize, String text) {
|
||||
try {
|
||||
return (font.getStringWidth(text) / 1000.0f) * fontSize;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("PDF 파일 출력 중 오류가 발생하였습니다.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 출력할 텍스트가 지정한 영역 안에 들어가지 않을 경우 줄바꿈 처리를 위해 텍스트를 나누어 배열로 반환한다.
|
||||
*/
|
||||
public String[] splitByLineForLargeText(PDType0Font font, int fontSize, String allText, float textAreaWidth_pt) {
|
||||
|
||||
float allTextWidth = calcTextWidth(font, fontSize, allText);
|
||||
|
||||
if(allText.equals("") || allText.length() == 1 || textAreaWidth_pt == 0
|
||||
|| (allTextWidth <= textAreaWidth_pt)
|
||||
) {
|
||||
return new String[] { allText };
|
||||
}
|
||||
|
||||
ArrayList<String> textList = new ArrayList<String>();
|
||||
|
||||
while(!allText.equals("")) {
|
||||
int lengthForLine = this.getLengthForLine(font, fontSize, allText, textAreaWidth_pt);
|
||||
String newLine = allText.substring(0,lengthForLine);
|
||||
textList.add(newLine);
|
||||
allText = allText.substring(lengthForLine);
|
||||
}
|
||||
|
||||
return textList.toArray(new String[textList.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 텍스트를 줄바꿈 처리할 경우 첫 라인에 출력될 글자 수를 반환한다.
|
||||
*/
|
||||
private int getLengthForLine(PDType0Font font, int fontSize, String allText, float textAreaWidth_pt) {
|
||||
int forLine = allText.length();
|
||||
if(forLine <= 1) {
|
||||
return forLine;
|
||||
};
|
||||
|
||||
for( ; ; forLine--) {
|
||||
if(forLine == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
boolean hit = ( this.calcTextWidth(font, fontSize, allText.substring(0, forLine)) <= textAreaWidth_pt );
|
||||
if(hit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return forLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* pdf에 이미지를 삽입한다.
|
||||
*/
|
||||
public void insertImage(PDDocument doc, PDPageContentStream contentStream, InputStream imageStream, float[] XYmm,
|
||||
float[] SIZEmm) {
|
||||
|
||||
float[] xyAbsolute = this.toPDFCoordinate(XYmm).absolute();
|
||||
|
||||
float[] size = new float[] {
|
||||
mmToPt(SIZEmm[0]),mmToPt(SIZEmm[1])
|
||||
};
|
||||
try {
|
||||
|
||||
PDImageXObject image = PDImageXObject.createFromByteArray(doc, imageStream.readAllBytes(), "temp");
|
||||
contentStream.drawImage(image, xyAbsolute[0], xyAbsolute[1]-size[1], size[0], size[1]);
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("PDF 파일 출력 중 오류가 발생하였습니다."+e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<PstnAndSize> devideImageArea(float[] totAreaPstn, float[] totAreaSize, int imageCntSetting, int dataImageCnt) {
|
||||
List<PstnAndSize> result = new ArrayList<PstnAndSize>();
|
||||
|
||||
int printable = imageCntSetting <= dataImageCnt ? imageCntSetting : dataImageCnt;
|
||||
|
||||
if(printable <= 1) {
|
||||
result.add(new PstnAndSize(totAreaPstn[0], totAreaPstn[1], totAreaSize[0], totAreaSize[1]));
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean longerThenWidth = totAreaSize[1] > totAreaSize[0];
|
||||
|
||||
int xLengthOfD2 = 0;
|
||||
int yLengthOfD2 = 0;
|
||||
|
||||
if(printable == 2){
|
||||
if(longerThenWidth) {
|
||||
xLengthOfD2 = 1;
|
||||
yLengthOfD2 = 2;
|
||||
} else {
|
||||
xLengthOfD2 = 2;
|
||||
yLengthOfD2 = 1;
|
||||
}
|
||||
} else if(printable == 3 || printable == 4){
|
||||
xLengthOfD2 = 2;
|
||||
yLengthOfD2 = 2;
|
||||
} else if(printable == 5 || printable == 6){
|
||||
if(longerThenWidth) {
|
||||
xLengthOfD2 = 2;
|
||||
yLengthOfD2 = 3;
|
||||
} else {
|
||||
xLengthOfD2 = 3;
|
||||
yLengthOfD2 = 2;
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("PDF 파일 출력 중 오류가 발생하였습니다.");
|
||||
}
|
||||
|
||||
PstnAndSize[][] d2Array = new PstnAndSize[xLengthOfD2][yLengthOfD2];
|
||||
Size cellSize = new Size(totAreaSize[0] / (xLengthOfD2 * 1.0f), totAreaSize[1] / (yLengthOfD2 * 1.0f));
|
||||
|
||||
d2Array[0][0] = new PstnAndSize(totAreaPstn[0], totAreaPstn[1], cellSize.getWidth(), cellSize.getHeight());
|
||||
d2Array = this.fillImageCells(d2Array);
|
||||
|
||||
//출력영역 크기 병합
|
||||
if(printable == 3 || printable == 5) {
|
||||
|
||||
boolean longerThenWidth_cell = cellSize.getHeight() > cellSize.getWidth();
|
||||
if(longerThenWidth_cell) {
|
||||
d2Array = this.mergeLastImageCell(d2Array, "left");
|
||||
} else {
|
||||
d2Array = this.mergeLastImageCell(d2Array, "up");
|
||||
}
|
||||
|
||||
}
|
||||
for(int y=0; y < yLengthOfD2; y++) {
|
||||
for(int x=0; x < xLengthOfD2; x++) {
|
||||
if(d2Array[x][y] != null) {
|
||||
result.add(d2Array[x][y]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private PstnAndSize[][] fillImageCells(PstnAndSize[][] d2) {
|
||||
int xLengthOfD2 = d2.length;
|
||||
int yLengthOfD2 = d2[0].length;
|
||||
|
||||
PstnAndSize firstCell = d2[0][0];
|
||||
|
||||
Size cellSize = firstCell.getSize();
|
||||
float cellWidth = cellSize.getWidth();
|
||||
float cellHeight = cellSize.getHeight();
|
||||
|
||||
Pstn startPoint = firstCell.getPstn();
|
||||
float spX = startPoint.getLeft();
|
||||
float spY = startPoint.getTop();
|
||||
|
||||
for(int x=0; x < xLengthOfD2; x++) {
|
||||
for(int y=0; y < yLengthOfD2; y++) {
|
||||
if(x != 0 || y != 0) {
|
||||
d2[x][y] = new PstnAndSize(spX + (cellWidth * (x * 1.0f)), spY + (cellHeight * (y * 1.0f)), cellSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return d2;
|
||||
}
|
||||
|
||||
public PstnAndSize[][] mergeLastImageCell(PstnAndSize[][] d2, String mergeDirection) {
|
||||
if(!mergeDirection.equals("up") && !mergeDirection.equals("left")) {
|
||||
throw new RuntimeException("PDF 파일 출력 중 오류가 발생하였습니다.");
|
||||
}
|
||||
|
||||
int xLengthOfD2 = d2.length;
|
||||
int yLengthOfD2 = d2[0].length;
|
||||
|
||||
int lastCellIndexX = xLengthOfD2-1;
|
||||
int lastCellIndexY = yLengthOfD2-1;
|
||||
|
||||
int mergeTargetCellIndexX = 0;
|
||||
int mergeTargetCellIndexY = 0;
|
||||
|
||||
if(mergeDirection.equals("up")) {
|
||||
mergeTargetCellIndexX = lastCellIndexX;
|
||||
mergeTargetCellIndexY = lastCellIndexY-1;
|
||||
}
|
||||
if(mergeDirection.equals("left")) {
|
||||
mergeTargetCellIndexX = lastCellIndexX-1;
|
||||
mergeTargetCellIndexY = lastCellIndexY;
|
||||
}
|
||||
|
||||
//병합대상셀
|
||||
if(mergeDirection.equals("up")) {
|
||||
d2[mergeTargetCellIndexX][mergeTargetCellIndexY] = (d2[mergeTargetCellIndexX][mergeTargetCellIndexY]).x2Height();
|
||||
}
|
||||
if(mergeDirection.equals("left")) {
|
||||
d2[mergeTargetCellIndexX][mergeTargetCellIndexY] = (d2[mergeTargetCellIndexX][mergeTargetCellIndexY]).x2Width();
|
||||
}
|
||||
|
||||
//마지막셀
|
||||
d2[lastCellIndexX][lastCellIndexY] = null;
|
||||
|
||||
return d2;
|
||||
}
|
||||
|
||||
/**
|
||||
* pdf에 봉합선을 넣는다.
|
||||
*/
|
||||
public void renderFoldLine(PDPageContentStream contentStream, PDRectangle paper, String foldCode) {
|
||||
if(foldCode.equals("") && !foldCode.equals("01") && !foldCode.equals("02")) {
|
||||
return;
|
||||
}
|
||||
|
||||
float paperWidth = paper.getWidth();
|
||||
|
||||
float partHeight;
|
||||
if(foldCode.equals("01")) {
|
||||
if(paper.A4.equals(paper)) {
|
||||
partHeight = 99;
|
||||
} else {
|
||||
partHeight = 93;
|
||||
}
|
||||
} else {
|
||||
partHeight = 93;
|
||||
}
|
||||
|
||||
float margin = 0;
|
||||
if(foldCode.equals("02")) {
|
||||
margin = 18;
|
||||
}
|
||||
|
||||
float bottomFold = margin + partHeight; //하단접는곳
|
||||
float topFold = margin + (partHeight * 2); //상단접는곳
|
||||
|
||||
float bottomFold_pt = mmToPt(bottomFold);
|
||||
float topFold_pt = mmToPt(topFold);
|
||||
|
||||
try {
|
||||
contentStream.setLineDashPattern(new float[]{3,1}, 0);
|
||||
contentStream.moveTo(0, topFold_pt);
|
||||
contentStream.lineTo(paperWidth, topFold_pt);
|
||||
contentStream.stroke();
|
||||
contentStream.moveTo(0, bottomFold_pt);
|
||||
contentStream.lineTo(paperWidth, bottomFold_pt);
|
||||
contentStream.stroke();
|
||||
contentStream.setLineDashPattern(new float[]{}, 0);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("PDF 파일 출력 중 오류가 발생하였습니다."+e);
|
||||
}
|
||||
}
|
||||
|
||||
public float[] getPstnStng(DefaultOtptArtclStng prototypeStng, DataObject sggStng, String paperSeCd) {
|
||||
if(!sggStng.string("LEFT_PSTN").equals("") && !sggStng.string("TOP_PSTN").equals("")) {
|
||||
return new float[] {
|
||||
sggStng.number("LEFT_PSTN").floatValue(),
|
||||
sggStng.number("TOP_PSTN").floatValue()
|
||||
};
|
||||
} else {
|
||||
return new float[] {
|
||||
prototypeStng.getLeftPstn(paperSeCd),
|
||||
prototypeStng.getTopPstn(paperSeCd)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public PDType0Font getFontType(DefaultOtptArtclStng prototypeStng, DataObject sggStng, Map<String, PDType0Font> fontMap) {
|
||||
if(sggStng != null && !sggStng.isEmpty() && !sggStng.string("FONT_NM").equals("")) {
|
||||
return fontMap.get(sggStng.string("FONT_NM"));
|
||||
} else {
|
||||
return fontMap.get(prototypeStng.getFontNm());
|
||||
}
|
||||
}
|
||||
|
||||
public int getFontSize(DefaultOtptArtclStng prototypeStng, DataObject sggStng) {
|
||||
if(!sggStng.string("FONT_SZ").equals("")) {
|
||||
return sggStng.number("FONT_SZ").intValue();
|
||||
} else {
|
||||
return prototypeStng.getFontSz();
|
||||
}
|
||||
}
|
||||
|
||||
public RenderingMode getFontStyle(DefaultOtptArtclStng prototypeStng, DataObject sggStng) {
|
||||
if(!sggStng.string("FONT_STYLE").equals("")) {
|
||||
return RenderingMode.valueOf(sggStng.string("FONT_STYLE"));
|
||||
} else {
|
||||
return RenderingMode.valueOf(prototypeStng.getFontStyle());
|
||||
}
|
||||
}
|
||||
|
||||
public PDColor getFontColor(DefaultOtptArtclStng prototypeStng, DataObject sggStng) {
|
||||
if(!sggStng.string("FONT_COLOR").equals("")) {
|
||||
return PDFColors.getColor(sggStng.string("FONT_COLOR"));
|
||||
} else {
|
||||
return PDFColors.getColor(prototypeStng.getFontColor());
|
||||
}
|
||||
}
|
||||
|
||||
public float[] getSize(DefaultOtptArtclStng prototypeStng, DataObject sggStng) {
|
||||
if(!sggStng.string("WIDTH_SZ").equals("")) {
|
||||
return new float[] {
|
||||
sggStng.number("WIDTH_SZ").floatValue(),
|
||||
sggStng.number("HEIGHT_SZ").floatValue()
|
||||
};
|
||||
} else {
|
||||
return new float[] {
|
||||
prototypeStng.getWidthSz(),
|
||||
prototypeStng.getHeightSz()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public String getAlign(DefaultOtptArtclStng prototypeStng, DataObject sggStng) {
|
||||
if(!sggStng.string("TEXT_SORT").equals("")) {
|
||||
return sggStng.string("TEXT_SORT");
|
||||
} else {
|
||||
return prototypeStng.getTextSort();
|
||||
}
|
||||
}
|
||||
|
||||
public String getLineChgYn(DefaultOtptArtclStng prototypeStng, DataObject sggStng) {
|
||||
if(!sggStng.string("LINE_CHG_YN").equals("")) {
|
||||
return sggStng.string("LINE_CHG_YN");
|
||||
} else {
|
||||
return prototypeStng.getLineChgYn();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, PDType0Font> getFontMap(PDDocument doc) {
|
||||
try {
|
||||
Map<String, PDType0Font> fontMap = Map.of(
|
||||
"notokrBold", PDType0Font.load(doc, new ClassPathResource("fonts/notokr-bold.ttf").getInputStream()),
|
||||
"gulim", PDType0Font.load(doc, new ClassPathResource("fonts/gulim.ttf").getInputStream()),
|
||||
"gulimche", PDType0Font.load(doc, new ClassPathResource("fonts/gulimche.ttf").getInputStream()),
|
||||
"batang", PDType0Font.load(doc, new ClassPathResource("fonts/batang.ttf").getInputStream()),
|
||||
"batangche", PDType0Font.load(doc, new ClassPathResource("fonts/batangche.ttf").getInputStream()),
|
||||
"dotum", PDType0Font.load(doc, new ClassPathResource("fonts/dotum.ttf").getInputStream()),
|
||||
"dotumche", PDType0Font.load(doc, new ClassPathResource("fonts/dotumche.ttf").getInputStream()),
|
||||
"gungsuh", PDType0Font.load(doc, new ClassPathResource("fonts/gungsuh.ttf").getInputStream()),
|
||||
"gungsuhche", PDType0Font.load(doc, new ClassPathResource("fonts/gungsuhche.ttf").getInputStream())
|
||||
);
|
||||
return fontMap;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("글꼴 로드 오류"+e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,49 @@
|
||||
package cokr.xit.fims.sprt;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import cokr.xit.fims.cmmn.pdf.PstnAndSize;
|
||||
import cokr.xit.foundation.data.DataObject;
|
||||
|
||||
public class MediaUtil {
|
||||
|
||||
public static List<PstnAndSize> getTransformedMosaic(List<DataObject> mosaicInfos, InputStream inputStream, PstnAndSize pstnAndSize_in_print) {
|
||||
List<PstnAndSize> result = new ArrayList<>();
|
||||
|
||||
try {
|
||||
|
||||
BufferedImage image = ImageIO.read(inputStream);
|
||||
float originalWidth = image.getWidth(null);
|
||||
float originalHeight = image.getHeight(null);
|
||||
float transX = pstnAndSize_in_print.getWidth() / originalWidth;
|
||||
float transY = pstnAndSize_in_print.getHeight() / originalHeight;
|
||||
|
||||
if(mosaicInfos != null) {
|
||||
for(int k=0; k < mosaicInfos.size(); k++) {
|
||||
DataObject mosaicInfo = mosaicInfos.get(k);
|
||||
float x = mosaicInfo.number("X_AXS").floatValue();
|
||||
float y = mosaicInfo.number("Y_AXS").floatValue();
|
||||
float w = mosaicInfo.number("MOSC_LT").floatValue();
|
||||
float h = mosaicInfo.number("MOSC_HG").floatValue();
|
||||
|
||||
PstnAndSize mosaic = new PstnAndSize(x, y, w, h);
|
||||
mosaic.transXY(transX, transY);
|
||||
mosaic.addPstn(pstnAndSize_in_print.getPstn());
|
||||
|
||||
result.add(mosaic);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("이미지 모자이크 처리 오류");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue