aspose-tasks-for-net 안녕 친구들! 오늘 블로그에서는 최신 Aspose.Tasks API를 소개합니다. Aspose 팀의 좋은 점은 Aspose.Tasks용 .NET 및 Java 기반 API를 매월 동시에 게시한다는 것입니다. .NET 및 Java 기반 변형은 기능 측면에서 동일한 수준이며 두 API 사용자는 각각의 환경에서 새로운 기능을 탐색할 수 있습니다. 다음 섹션에서는 API에서 제공하는 새로운 기능과 개선 사항에 대해 논의할 것입니다.

C# 및 Java에서 Microsoft 프로젝트 파일에 메타데이터 쓰기

Aspose.Tasks는 일정, 작업, 작업 링크, 리소스 및 리소스 할당을 위해 MPP 파일에 메타데이터를 작성하는 기능을 제공합니다. 다음 예에서는 MPP 파일에 메타데이터 정보를 쓰는 방법을 설명합니다.

동일한 Java 기반 구현은 다음과 같습니다.

// 문서 디렉토리의 경로입니다.
String dataDir = Utils.getDataDir(WriteMetadata.class);

long OneSec = 10000000;
long OneMin = 60 * OneSec;
long OneHour = 60 * OneMin;
long OneDayEightHour = 8 * OneHour;
long OneDayTwentyFourHour = 24 * OneHour;

Project project = new Project(dataDir + "New project 2010.mpp");
java.util.Calendar calendar = java.util.Calendar.getInstance(TimeZone.getTimeZone("GMT"));
calendar.set(2012, java.util.Calendar.DECEMBER, 7, 0, 0, 0);
Date startDate = calendar.getTime();
calendar.set(2013, java.util.Calendar.DECEMBER, 7, 0, 0, 0);
Date toDate = calendar.getTime();

WorkingTime wt = new WorkingTime();
wt.setFromTime(startDate);
wt.setToTime(toDate);

WeekDay day = project.get(Prj.CALENDAR).getWeekDays().toList().get(1);
day.getWorkingTimes().add(wt);

project.get(Prj.CALENDAR).setName("CHANGED NAME!");

Task task = project.getRootTask().getChildren().add("Task 1");
task.set(Tsk.DURATION_FORMAT, TimeUnitType.Day);
task.set(Tsk.DURATION, project.getDuration(3));
task.set(Tsk.CONTACT, "Rsc 1");
// 새로운 분야
task.set(Tsk.IS_MARKED, true);
task.set(Tsk.IGNORE_WARNINGS, true);

Task task2 = project.getRootTask().getChildren().add("Task 2");
task2.set(Tsk.DURATION_FORMAT, TimeUnitType.Day);
task2.set(Tsk.CONTACT, "Rsc 2");

project.getTaskLinks().add(task, task2, TaskLinkType.FinishToStart, project.getDuration(-1, TimeUnitType.Day));

calendar.set(2013, java.util.Calendar.DECEMBER, 13, 9, 0, 0);
startDate = calendar.getTime();
project.set(Prj.START_DATE, startDate);

Resource rsc = project.getResources().add("Rsc 1");
rsc.set(Rsc.TYPE, ResourceType.Work);
rsc.set(Rsc.INITIALS, "WR");
rsc.set(Rsc.ACCRUE_AT, CostAccrualType.Prorated);
rsc.set(Rsc.MAX_UNITS, 1d);
rsc.set(Rsc.CODE, "Code 1");
rsc.set(Rsc.GROUP, "Workers");
rsc.set(Rsc.E_MAIL_ADDRESS, "1@gmail.com");
rsc.set(Rsc.WINDOWS_USER_ACCOUNT, "user_acc1");
rsc.set(Rsc.IS_GENERIC, new NullableBool(true));
rsc.set(Rsc.ACCRUE_AT, CostAccrualType.End);
rsc.set(Rsc.STANDARD_RATE, BigDecimal.valueOf(10));
rsc.set(Rsc.STANDARD_RATE_FORMAT, RateFormatType.Day);
rsc.set(Rsc.OVERTIME_RATE, BigDecimal.valueOf(15));
rsc.set(Rsc.OVERTIME_RATE_FORMAT, RateFormatType.Hour);

rsc.set(Rsc.IS_TEAM_ASSIGNMENT_POOL, true);
rsc.set(Rsc.COST_CENTER, "Cost Center 1");

ResourceAssignment assn = project.getResourceAssignments().add(task, rsc);
assn.set(Asn.UID, 1);
assn.set(Asn.WORK, task.get(Tsk.DURATION));
assn.set(Asn.REMAINING_WORK, assn.get(Asn.WORK));
assn.set(Asn.REGULAR_WORK, assn.get(Asn.WORK));
task.set(Tsk.WORK, assn.get(Asn.WORK));

rsc.set(Rsc.WORK, task.get(Tsk.WORK));
assn.set(Asn.START, task.get(Tsk.START));
assn.set(Asn.FINISH, task.get(Tsk.FINISH));

// 프로젝트 및 작업에 대한 확장 속성 추가
ExtendedAttributeDefinition attr = ExtendedAttributeDefinition.createTaskDefinition(CustomFieldType.Flag,
        ExtendedAttributeTask.Flag1, "My Flag Field");
project.getExtendedAttributes().add(attr);

ExtendedAttribute taskAttr = attr.createExtendedAttribute();
taskAttr.setFlagValue(true);
task2.getExtendedAttributes().add(taskAttr);

project.save(dataDir + "updated.mpp", SaveFileFormat.MPP);

수식 읽기 및 쓰기

Aspose.Tasks API는 MPP 프로젝트 파일에 대한 수식 읽기/쓰기를 지원합니다. ExtendedAttributeDefinition의 Formula 속성은 수식 값을 읽기 위한 인터페이스를 제공합니다. 다음 예에서는 MPP 파일에서 엔터프라이즈 확장 속성뿐 아니라 로컬에서 공식을 읽는 방법을 설명합니다. 또한 MPP 파일에 수식을 작성하는 방법을 보여줍니다.

MPP 파일에서 로컬 및 엔터프라이즈 확장 속성의 수식 읽기

동일한 Java 기반 구현은 다음과 같습니다.

// 문서 디렉토리의 경로입니다.
String dataDir = Utils.getDataDir(WriteReadFormula.class);

Project proj = new Project(dataDir + "FormulaField.mpp"); // attached test mpp
ExtendedAttributeDefinition attr = proj.getExtendedAttributes().get(0);

System.out.println("Attribute Formula: " + attr.getFormula());

확장 속성의 수식을 MPP 파일 형식에 쓰기

동일한 Java 기반 구현은 다음과 같습니다.

// 문서 디렉토리의 경로입니다.
String dataDir = Utils.getDataDir(WriteReadFormula.class);

Project project = new Project(dataDir + "New project 2010.mpp");
project.set(Prj.NEW_TASKS_ARE_MANUAL, new NullableBool(false));

// 작업 비용을 두 배로 늘리는 수식으로 새 사용자 정의 필드(작업 Text1)를 만듭니다.
ExtendedAttributeDefinition attr = ExtendedAttributeDefinition.createTaskDefinition(CustomFieldType.Text,
        ExtendedAttributeTask.Text1, "Custom");
attr.setAlias("Double Costs");
attr.setFormula("[Cost]*2");

project.getExtendedAttributes().add(attr);

// MSP에서 결과를 보기 위한 작업 추가
Task task = project.getRootTask().getChildren().add("Task");
// 작업 비용 설정
task.set(Tsk.COST, BigDecimal.valueOf(100));
// 첨부된 스크린샷에서 결과 확인(result.jpg)
project.save(dataDir + "saved.mpp", SaveFileFormat.MPP);

중첩 리소스에 대한 리소스 접두사 구현

Aspose.Tasks는 중첩된 리소스(예: SVG 파일 내 PNG)를 별도의 폴더에 저장할 수 있는 ResourceSavingArgs.NestedUri 속성을 제공합니다. 다음 예에서는 이 기능을 사용하는 사용 사례를 보여주었습니다.

동일한 Java 기반 구현은 다음과 같습니다.

public class ResourcePrefixForNestedResources implements IFontSavingCallback, ICssSavingCallback, IImageSavingCallback {

    public static String dataDir = Utils.getDataDir(ResourcePrefixForNestedResources.class);

    public static void main(String[] args) throws IOException {
        FileInputStream fs = new FileInputStream(dataDir + "Project1.mpp");
        Project project = new Project(fs);
        HtmlSaveOptions options = GetSaveOptions(1);
        FileOutputStream stream = new FileOutputStream(dataDir + "document.html");
        project.save(stream, options);
    }

    public void cssSaving(CssSavingArgs args) {
        FileOutputStream stream;
        try {
            stream = new FileOutputStream(dataDir + "css/" + args.getFileName());
            args.setStream(stream);
            args.setKeepStreamOpen(false);
            args.setUri(dataDir + "css/" + args.getFileName());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public void fontSaving(FontSavingArgs args) {
        FileOutputStream stream;
        try {
            stream = new FileOutputStream(dataDir + "fonts/" + args.getFileName());
            args.setStream(stream);
            args.setKeepStreamOpen(false);
            args.setUri(dataDir + "fonts/" + args.getFileName());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public void imageSaving(ImageSavingArgs args) {
        if (args.getFileName().endsWith("png")) {
            FileOutputStream stream1;
            try {
                stream1 = new FileOutputStream(dataDir + "resources/nestedResources/" + args.getFileName());
                args.setStream(stream1);
                args.setKeepStreamOpen(false);
                args.setUri(dataDir + "resources/" + args.getFileName());
                args.setNestedUri(dataDir + "nestedResources/" + args.getFileName());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        } else {
            FileOutputStream stream2;
            try {
                stream2 = new FileOutputStream(dataDir + "resources/" + args.getFileName());
                args.setStream(stream2);
                args.setKeepStreamOpen(false);
                args.setUri(dataDir + "resources/" + args.getFileName());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    private static HtmlSaveOptions GetSaveOptions(int pageNumber) {
        HtmlSaveOptions saveOptions = new HtmlSaveOptions();
        saveOptions.setIncludeProjectNameInPageHeader(false);
        saveOptions.setIncludeProjectNameInTitle(false);
        saveOptions.setPageSize(PageSize.A3);
        saveOptions.setTimescale(Timescale.ThirdsOfMonths);
        saveOptions.setReduceFooterGap(true);
        saveOptions.setFontFaceTypes(FontFaceType.Ttf);
        saveOptions.setExportCss(ResourceExportType.AsFile);
        saveOptions.setExportFonts(ResourceExportType.AsFile);
        saveOptions.setExportImages(ResourceExportType.AsFile);

        ResourcePrefixForNestedResources program = new ResourcePrefixForNestedResources();
        saveOptions.setFontSavingCallback(program);
        saveOptions.setCssSavingCallback(program);
        saveOptions.setImageSavingCallback(program);

        saveOptions.getPages().clear();
        saveOptions.getPages().add(pageNumber);

        File dirFonts = new File(dataDir + "fonts");
        if (!dirFonts.exists()) {
            dirFonts.mkdir();
        }

        File dirResources = new File(dataDir + "resources");
        if (!dirResources.exists()) {
            dirResources.mkdir();
        }

        File dirNResources = new File(dataDir + "nestedResources");
        if (!dirNResources.exists()) {
            dirNResources.mkdir();
        }

        File dirCSS = new File(dataDir + "css");
        if (!dirCSS.exists()) {
            dirCSS.mkdir();
        }

        return saveOptions;
    }

}

확장 속성 작업

Microsoft Project(MSP)에는 응용 프로그램 간에 정보를 교환하고 프로젝트 파일을 사용하여 프로그래밍하는 것을 더 쉽게 만드는 광범위한 XML 데이터 교환 스키마가 있습니다. 스키마를 사용하면 작업, 리소스 및 할당에 확장된 속성을 추가할 수 있습니다. 이 문서에서는 Aspose.Tasks에서 확장 속성을 사용하는 방법을 보여줍니다.

Resource 클래스에 의해 노출된 ExtendedAttribute 속성은 리소스의 확장된 속성을 관리하는 데 사용할 수 있습니다. 이 속성은 리소스의 확장 속성을 처리하기 위해 ExtendedAttribute 개체의 ArrayList를 읽고 씁니다. ExtendedAttribute 개체는 관련 속성을 추가로 노출합니다.

동일한 Java 기반 구현은 다음과 같습니다.

// 문서 디렉토리의 경로입니다.
String dataDir = Utils.getDataDir(ExtendedResourceAttributes.class);

Project prj = new Project(dataDir + "project5.mpp");

// 확장 속성 정의
ExtendedAttributeDefinition myNumber1 = prj.getExtendedAttributes()
        .getById((int) ExtendedAttributeTask.Number1);
if (myNumber1 == null) {
    myNumber1 = ExtendedAttributeDefinition.createResourceDefinition(ExtendedAttributeResource.Number1, "Age");
    prj.getExtendedAttributes().add(myNumber1);
}

// 확장 속성 생성 및 값 설정
ExtendedAttribute number1Resource = myNumber1.createExtendedAttribute();
number1Resource.setNumericValue(BigDecimal.valueOf(30.5345));

// 새 리소스 및 해당 확장 속성 추가
Resource rsc = prj.getResources().add("R1");
rsc.getExtendedAttributes().add(number1Resource);

prj.save(dataDir + "Project5.xml", SaveFileFormat.XML);

// 변환 결과를 표시합니다.
System.out.println("Process completed Successfully");

렌더링 개선

이번 릴리스에서는 API의 렌더링 성능 향상에도 초점을 맞췄습니다. PDF 및 HTML 렌더링 문제도 해결되었습니다. 기타 개선 사항에는 MPP 파일 열기 및 저장, 잘못된 작업 ID 및 타임라인과 관련된 문제 해결이 포함됩니다.

이 릴리스에는 다른 많은 기능, 개선 사항 및 버그 수정이 포함되어 있습니다. 여기에서 세부 정보를 얻을 수 있습니다!

또한 사용자가 즉시 다른 샘플을 사용하고 API 기능을 탐색할 수 있도록 Github에서 .NET 및 Java 기반 API에 대한 작업 샘플 예제를 유지 관리했습니다. 제품 지원 포럼에서 API 관련 문제에 대해 이야기할 수도 있습니다.